История изменений
Исправление KivApple, (текущая версия) :
У меня есть такой вопрос... как можно сделать нормальную критическую секцию при использовании pthreads? Ну то есть гарантировать, что код внутри неё не будет вызван конкурентно и кеширование данных используемых внутри не случится снаружи (ну если только мы явно не создадим локальную переменную, которой присвоим значение до вхождения в критическую секцию).
Сейчас сделано так:
void CriticalSection::enter() {
int r = pthread_mutex_lock(&m_mutex);
assert(r == 0);
asm volatile("":::"memory");
__sync_synchronize();
}
void CriticalSection::leave() {
__sync_synchronize();
asm volatile("":::"memory");
pthread_mutex_unlock(&m_mutex);
}
Меня не очень беспокоит производительность, потому что код в критической секции небольшой и его не планируется вызывать миллионы раз в секунду. На микроконтроллере я просто запрещаю прерывания + вставлю asm volatile("":::«memory»), а вот под Linux вышеприведённого кода недостаточно. Ибо односвязные списки всё равно иногда портятся, несмотря на то что любая модификация (добавление или удаление) происходит только между enter и leave.
Исходная версия KivApple, :
У меня есть такой вопрос... как можно сделать нормальную критическую секцию при использовании pthreads? Ну то есть гарантировать, что код внутри неё не будет вызван конкурентно и кеширование данных используемых внутри не случится снаружи (ну если только мы явно не создадим локальную переменную, которой присвоим значение до вхождения в критическую секцию).
Сейчас сделать так:
void CriticalSection::enter() {
int r = pthread_mutex_lock(&m_mutex);
assert(r == 0);
asm volatile("":::"memory");
__sync_synchronize();
}
void CriticalSection::leave() {
__sync_synchronize();
asm volatile("":::"memory");
pthread_mutex_unlock(&m_mutex);
}
Меня не очень беспокоит производительность, потому что код в критической секции небольшой и его не планируется вызывать миллионы раз в секунду. На микроконтроллере я просто запрещаю прерывания + вставлю asm volatile("":::«memory»), а вот под Linux вышеприведённого кода недостаточно. Ибо односвязные списки всё равно иногда портятся, несмотря на то что любая модификация (добавление или удаление) происходит только между enter и leave.