2022-04-12 12:20:17 +00:00
|
|
|
#ifndef COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_
|
|
|
|
#define COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_
|
2022-06-19 08:13:03 +00:00
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
|
|
COSMOPOLITAN_C_START_
|
2022-05-17 11:14:28 +00:00
|
|
|
|
2022-06-13 02:33:42 +00:00
|
|
|
#ifdef TINY
|
|
|
|
#define _spinlock(lock) _spinlock_tiny(lock)
|
2022-04-20 16:56:53 +00:00
|
|
|
#else
|
2022-06-13 02:33:42 +00:00
|
|
|
#define _spinlock(lock) _spinlock_cooperative(lock)
|
2022-04-20 16:56:53 +00:00
|
|
|
#endif
|
2022-04-12 12:20:17 +00:00
|
|
|
|
2022-06-19 08:13:03 +00:00
|
|
|
#define _spunlock(lock) (__atomic_store_n(lock, 0, __ATOMIC_RELAXED), 0)
|
2022-05-14 11:33:58 +00:00
|
|
|
|
2022-06-13 02:33:42 +00:00
|
|
|
#define _seizelock(lock, value) \
|
|
|
|
({ \
|
2022-05-19 23:57:49 +00:00
|
|
|
autotype(lock) __lock = (lock); \
|
2022-05-21 01:51:41 +00:00
|
|
|
typeof(*__lock) __x = (value); \
|
2022-05-19 23:57:49 +00:00
|
|
|
__atomic_store(__lock, &__x, __ATOMIC_RELEASE); \
|
2022-06-13 02:33:42 +00:00
|
|
|
})
|
2022-04-12 12:20:17 +00:00
|
|
|
|
2022-06-16 16:06:09 +00:00
|
|
|
#define _spinlock_tiny(lock) \
|
|
|
|
({ \
|
|
|
|
while (_trylock(lock)) { \
|
|
|
|
__builtin_ia32_pause(); \
|
|
|
|
} \
|
|
|
|
0; \
|
2022-06-13 02:33:42 +00:00
|
|
|
})
|
2022-05-14 11:33:58 +00:00
|
|
|
|
2022-05-19 23:57:49 +00:00
|
|
|
#define _spinlock_cooperative(lock) \
|
2022-06-16 16:06:09 +00:00
|
|
|
({ \
|
|
|
|
char __x; \
|
|
|
|
volatile int __i; \
|
|
|
|
unsigned __tries = 0; \
|
|
|
|
char *__lock = (lock); \
|
|
|
|
for (;;) { \
|
|
|
|
__atomic_load(__lock, &__x, __ATOMIC_RELAXED); \
|
|
|
|
if (!__x && !_trylock(__lock)) { \
|
|
|
|
break; \
|
|
|
|
} else if (__tries < 7) { \
|
|
|
|
for (__i = 0; __i != 1 << __tries; __i++) { \
|
|
|
|
} \
|
|
|
|
__tries++; \
|
|
|
|
} else { \
|
|
|
|
_spinlock_yield(); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
0; \
|
|
|
|
})
|
|
|
|
|
2022-06-13 02:33:42 +00:00
|
|
|
#define _trylock(lock) __atomic_test_and_set(lock, __ATOMIC_SEQ_CST)
|
2022-05-14 11:33:58 +00:00
|
|
|
|
2022-06-19 08:13:03 +00:00
|
|
|
int _spinlock_yield(void);
|
2022-05-14 11:33:58 +00:00
|
|
|
|
2022-06-19 08:13:03 +00:00
|
|
|
COSMOPOLITAN_C_END_
|
|
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
2022-04-12 12:20:17 +00:00
|
|
|
#endif /* COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ */
|