Легкие спин-блокировки, построенные из атомных операций GCC?
Я хотел бы минимизировать синхронизацию и писать код без блокировки, когда это возможно, в моем проекте. Когда это абсолютно необходимо, я бы с удовольствием заменил легкие спин-блокировки, созданные на атомарных операциях, на блокировки мьютексов pthread и win32. Насколько я понимаю, это системные вызовы внизу и могут вызвать переключение контекста (что может быть ненужным для очень быстрых критических секций, где было бы предпочтительнее просто несколько раз вращать).
Атомарные операции, на которые я ссылаюсь, хорошо документированы здесь:http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Atomic-Builtins.html
Вот пример, чтобы проиллюстрировать, о чем я говорю. Представьте себе RB-дерево с несколькими читателями и писателями. RBTree :: exist () доступна только для чтения и безопасна для потоков, а RBTree :: insert () потребует монопольного доступа одного автора (и никаких читателей) для безопасности. Некоторый код:
class IntSetTest
{
private:
unsigned short lock;
RBTree<int>* myset;
public:
// ...
void add_number(int n)
{
// Aquire once locked==false (atomic)
while (__sync_bool_compare_and_swap(&lock, 0, 0xffff) == false);
// Perform a thread-unsafe operation on the set
myset->insert(n);
// Unlock (atomic)
__sync_bool_compare_and_swap(&lock, 0xffff, 0);
}
bool check_number(int n)
{
// Increment once the lock is below 0xffff
u16 savedlock = lock;
while (savedlock == 0xffff || __sync_bool_compare_and_swap(&lock, savedlock, savedlock+1) == false)
savedlock = lock;
// Perform read-only operation
bool exists = tree->exists(n);
// Decrement
savedlock = lock;
while (__sync_bool_compare_and_swap(&lock, savedlock, savedlock-1) == false)
savedlock = lock;
return exists;
}
};
(допустим, он не должен быть безопасным для исключений)
Этот код действительно поточно-ориентированный? Есть ли плюсы / минусы этой идеи? Любой совет? Является ли использование таких спин-блокировок плохой идеей, если потоки не являются действительно параллельными?
Заранее спасибо. ;)