Tuvimos una discusión sobre cómo garantizar que los datos en alguna región de memoria compartida (no confiable) solo se acceda una vez, se copien en la memoria local y luego se verifiquen y procesen desde allí. El entorno es un µC multinúcleo integrado con RAM compartida para IPC, el código está escrito en C99. Actualmente, básicamente hacemos Type local_copy = *(Type*)shared_memory_pointer; y luego solo operar en local_copy después.
Ahora, un colega planteó la pregunta, si el compilador no podía realizar la copia en la memoria local y, en cambio, acceder a los datos en shared_memory_pointer directamente a continuación, lo que (en teoría) permitiría la manipulación de los datos mientras se usa.
¿Es posible que un compilador haga eso? Si es así, ¿cómo podemos asegurarnos de que no suceda? Si no, por favor explique los detalles.
¡Gracias a todos!
Editar: no hay sistema operativo en el núcleo en cuestión, es un sistema completo.
si se le permitió al compilador no realizar la copia en la memoria local y, en su lugar, acceder a los datos en shared_memory_pointer directamente
Sí, el compilador puede hacer eso. El único escenario en el que puede imponer una lectura es mediante un acceso calificado volatile . En su caso, tanto la variable local como el elenco deben calificarse como volatile .
Tenga en cuenta sin embargo ...
volatile no resuelve los problemas de reingreso. Necesita un mutex, una sección crítica o un medio similar para bloquear el código de los errores de condición de carrera. Utilice los medios proporcionados por su sistema operativo.Type local_copy = *(Type*)shared_memory_pointer; es un código muy sospechoso y sugiere que tiene un comportamiento indefinido o errores relacionados con el tipo en su programa. Los juegos de palabras de tipo salvaje como este pueden causar desalineación, optimizaciones de alias de puntero estrictas incorrectas, calificadores descartados, etc., todo ello con un comportamiento indefinido. Además, si ha elegido los tipos adecuados, no es necesario lanzarlos en primer lugar.Tuvimos una discusión sobre cómo garantizar que los datos en alguna región de memoria compartida (no confiable) solo se acceda una vez , se copien en la memoria local y luego se verifiquen y procesen desde allí.
Use memcpy con semáforo binario en lugar de juegos de palabras con punteros.
Ejemplo de freeRTOS: se asegura de que el
if(xSemaphoreTake( xSemaphoreSharedVariable, (TickType_t) 10 ) == pdTRUE) { taskENTER_CRITICAL(); //make sure that the shared resource will not be changed during not atomic access memcpy(&local_copy, shared_memory_pointer, sizeof(local_copy); taskEXIT_CRITICAL(); } else { /* the shared resource was alredsy read */ /* do something */ }