LINUX.ORG.RU

странный спинлок

 , ,


0

5

здравствуйте, в одной из реализаций стандартных библиотек си встретил следующую реализацию спинлока:

int pthread_spin_lock(pthread_spinlock_t *s)
{
	while (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin();
	return 0;
}

static void a_spin()
{
	volatile int tmp = 0;
	a_cas(&tmp, 0, 0);
}

что делает a_spin? что за магия

★★

Последнее исправление: xperious (всего исправлений: 2)

В musl есть аналогичная, где-то делает asm("pause":::"memory"), в другом месте:

#ifndef a_barrier
#define a_barrier a_barrier
static void a_barrier()
{
	volatile int tmp = 0;
	a_cas(&tmp, 0, 0);
}
#endif

#ifndef a_spin
#define a_spin a_barrier
#endif

Так что это, видимо, барьер для памяти, аналог sleep(0)/yield для атомиков.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от xaizek

не, я просто не могу понять концептуально, зачем заведомо нулевую переменную атомарно сравнивать и менять с нулем? зачем вообще этот код нужен

xperious ★★
() автор топика
Ответ на: комментарий от xperious

Хз. Но я слышал, что nop нельзя использовать, потому что ради оптимизаций интел что-то с ним сделали. Но не факт, что это относится к твоему кейсу.

ox55ff ★★★★★
()

Судя по этой реализации a_cas, здесь смысл в мембаре.

PRN
()

Спиниться еще одной атомарной операцией и постоянно дрочить шину, тормозя другие процессоры - это тупо. М - масштабируемость.

Pavval ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.