Разделяемая память и ее защита.
Добрый вечер, форумчане!
Имеется вопрос, есть в проекте (операционка QNX4.25) несколько разделяемых объектов памяти, для взаимодействия между процессами. Есть один писатель в каждую из них и несколько читателей, я написал несколько функций оберток вида:
void XXXX_ShmemLock()
{
assert( g_Shmem );
sem_wait( &g_Shmem->lock );
}
void XXXX_ShmemUnlock()
{
assert( g_Shmem );
sem_post( &g_Shmem->lock );
}
void XXXX_ShmemCopy( void *destination, const void *source, const size_t num )
{
XXXX_ShmemLock();
_disable();
memcpy( destination, source, num );
_enable();
XXXX_ShmemUnlock();
}
Дальнейшие операции более высокого уровня, выполняются путем вызова функций-оберток, как пример приложу:
void XXXX_ReadADC( const ADCChannel_t channel, double *voltage )
{
assert( channel < ADC_ChannelsNum );
// *voltage = g_Shmem->Vin[channel];
XXXX_ShmemCopy( (void *)voltage, (const void *)&g_Shmem->Vin[channel], sizeof(g_Shmem->Vin[channel]) );
}
void XXXX_WriteADC( const ADCChannel_t channel, const double voltage )
{
assert( channel < ADC_ChannelsNum );
// g_Shmem->Vin[channel] = voltage;
XXXX_ShmemCopy( (void *)&g_Shmem->Vin[channel], (const void *)&voltage, sizeof(voltage) );
}
Так вот, как видно в функции XXXX_ShmemCopy, копирование данных в область и из нее, производится вызовом memcpy, обернутым в семафор и дополнительным отключением прерываний на момент копирования, чтобы обеспечить атомарность операции. Есть ли вообще смысл в такой перестраховке на однопроцессорной системе? Минус в использовании _disable()/_enable() при больших объемах копирования (которых скорее всего не будет), на момент выполнения операции, стопорится работа всей системы, или если вызовов XXXX_ShmemCopy будет много (а их скорее всего будет много), то рискуем то и делать что бесконечно выключать/включать прерывания. Так же есть ли необходимость оборачивания простых операций вида «Область->переменная = что-то записать», понятное дело не делая справа от «=» сложных операций, будет ли такая операция выполнена атомарно?