LINUX.ORG.RU

История изменений

Исправление 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.