Estoy usando un bloqueo de giro para proteger una sección crítica muy pequeña. La contención ocurre muy raramente así que un bloqueo de giro es más apropiado que un mutex regular.¿La implementación de mi bloqueo de giro es correcta y óptima?
Mi código actual es la siguiente, y asume x86 y GCC:
volatile int exclusion = 0;
void lock() {
while (__sync_lock_test_and_set(&exclusion, 1)) {
// Do nothing. This GCC builtin instruction
// ensures memory barrier.
}
}
void unlock() {
__sync_synchronize(); // Memory barrier.
exclusion = 0;
}
Entonces me pregunto:
- Es este código correcto? ¿Asegura correctamente la exclusión mutua?
- ¿Funciona en todos los sistemas operativos x86?
- ¿Funciona también en x86_64? En todos los sistemas operativos?
- ¿Es óptimo?
- He visto implementaciones de bloqueo de giro usando compare-and-swap, pero no estoy seguro de cuál es mejor.
- De acuerdo con la documentación de los edificios atómicos de GCC (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html) también hay
__sync_lock_release
. No soy un experto en barreras de memoria, así que no estoy seguro de si puedo usar esto en lugar de__sync_synchronize
. - Estoy optimizando para el caso en el que no hay contención.
no me importa en absoluto sobre la contención. Puede haber 1, tal vez otros 2 hilos que intenten bloquear el bloqueo de giro una vez cada días.
Tengo curiosidad de por qué no está utilizando mutexes pthread. En el caso de no contención, un bloqueo o desbloqueo es solo un par de instrucciones. –
Estoy con Jay: si su propósito es acelerar su aplicación, en lugar de aprender cómo implementar un spinlock, entonces, antes de preocuparse por si esto es correcto, pruebe si en realidad es más rápido que un mutex. Si no, ¿a quién le importa si es correcto? –
Ya lo he probado. El spinlock * actual es * más rápido que un mutex, al menos en Linux. No estoy evitando mutexes posix sin una buena razón. – Hongli