Size: a a a

2020 June 07

R

Ruben in pro.cxx
Dollar Føølish
Што такое cpu_relax() ?
rep; nop
источник

DF

Dollar Føølish in pro.cxx
Спасибо
источник

R

Ruben in pro.cxx
я так понял, вызывает переключение контекста, либо дает поработать гипертредингу на короткое время
источник

AF

Aidar Fattakhov in pro.cxx
Aidar Fattakhov
что такое xadd?
если это обычный fetch_add то оно возвращает предыдущее значение
источник

R

Ruben in pro.cxx
я так понял это не fetch_add, а атомарный аналог xadd, то есть возвращает текущее значение
источник

R

Ruben in pro.cxx
Aidar Fattakhov
что такое xadd?
xadd это инструкция процессора: поменять регистры местами, сложить, и загрузить сумму в первый регистр. Соответственно, я предполагаю, что эта функция работает аналогичным образом.
источник

AF

Aidar Fattakhov in pro.cxx
ты где эту статью раскопал? закопай обратно
источник

R

Ruben in pro.cxx
Aidar Fattakhov
ты где эту статью раскопал? закопай обратно
мне её тут скинули, я пытаюсь раскурить, спрашивая заодно того, кто скинул)
источник

AF

Aidar Fattakhov in pro.cxx
Ruben
я так понял это не fetch_add, а атомарный аналог xadd, то есть возвращает текущее значение
че такое xadd?
источник

AF

Aidar Fattakhov in pro.cxx
read-modify-write операции возвращают предыдущее значение
источник

AT

Andrew Titov in pro.cxx
Ruben
что-то не пойму, как это работает.
static void rwticket_wrlock(rwticket *l)
{
 unsigned me = atomic_xadd(&l->u, (1<<16));
 unsigned char val = me >> 16;
 
 while (val != l->s.write) cpu_relax();
}

Сначала мы увеличиваем l->s.write с помощью атомарной функции atomic_xadd (побитовыми операциями добиваемся увеличения поля write). Результат увеличения сохраняем в me и получаем далее в val значение того самого write после атомарного инкретемента.
Далее в цикле ожидаем, пока val не станет равно текущему значению l->s.write.
Этот штука ничего не лочит, так как при любом исходном значении l->s.write условие в цикле не выполняется и мы покидаем lock()
Если никто больше не вызывает lock(), то она и не должна ничего блокировать.
источник

R

Ruben in pro.cxx
Andrew Titov
Если никто больше не вызывает lock(), то она и не должна ничего блокировать.
а если перед этим вызвали?
источник

R

Ruben in pro.cxx
другой тред вызвал, работает, и этот вызывает.
источник

AT

Andrew Titov in pro.cxx
Действительно...
источник

AF

Aidar Fattakhov in pro.cxx
Ruben
что-то не пойму, как это работает.
static void rwticket_wrlock(rwticket *l)
{
 unsigned me = atomic_xadd(&l->u, (1<<16));
 unsigned char val = me >> 16;
 
 while (val != l->s.write) cpu_relax();
}

Сначала мы увеличиваем l->s.write с помощью атомарной функции atomic_xadd (побитовыми операциями добиваемся увеличения поля write). Результат увеличения сохраняем в me и получаем далее в val значение того самого write после атомарного инкретемента.
Далее в цикле ожидаем, пока val не станет равно текущему значению l->s.write.
Этот штука ничего не лочит, так как при любом исходном значении l->s.write условие в цикле не выполняется и мы покидаем lock()
ты точно не пайпы изобретаешь?
источник

R

Ruben in pro.cxx
Aidar Fattakhov
ты точно не пайпы изобретаешь?
пайпы можно юзать как rwlock?
источник

AF

Aidar Fattakhov in pro.cxx
можно использовать как циклический буффер
источник

R

Ruben in pro.cxx
если честно, я кажется уже нашел rwlock для кросспроцессной работы. Это обычный pthread_mutex, с установленным атрибутом специальным, смапленный на shared memory
источник

R

Ruben in pro.cxx
я просто по инерции решил разобраться, а как самому сделать rwlock
источник

AF

Aidar Fattakhov in pro.cxx
мне кажется у тебя XY-problem, потомучто циклический буффер для тебя это кажется лишь способ написать очередь
источник