mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 11:37:35 +00:00
80 lines
2.3 KiB
C
80 lines
2.3 KiB
C
#include "third_party/chibicc/test/test.h"
|
|
|
|
#define SPINLOCK(lock) \
|
|
do { \
|
|
for (;;) { \
|
|
typeof(*(lock)) x; \
|
|
__atomic_load(lock, &x, __ATOMIC_RELAXED); \
|
|
if (!x && !__sync_lock_test_and_set(lock, 1)) { \
|
|
break; \
|
|
} else { \
|
|
__builtin_ia32_pause(); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
#define SPUNLOCK(lock) __sync_lock_release(lock)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define SPINLOCK2(lock) \
|
|
do { \
|
|
for (;;) { \
|
|
typeof(*(lock)) x; \
|
|
__atomic_load(lock, &x, __ATOMIC_RELAXED); \
|
|
if (!x && !__atomic_test_and_set(lock, __ATOMIC_SEQ_CST)) { \
|
|
break; \
|
|
} else { \
|
|
__builtin_ia32_pause(); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
#define SPUNLOCK2(lock) __sync_lock_release(lock)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
_Alignas(64) char lock;
|
|
|
|
main() {
|
|
int x, y;
|
|
|
|
ASSERT(0, lock);
|
|
SPINLOCK(&lock);
|
|
ASSERT(1, lock);
|
|
SPUNLOCK(&lock);
|
|
ASSERT(0, lock);
|
|
|
|
ASSERT(0, lock);
|
|
SPINLOCK2(&lock);
|
|
ASSERT(1, lock);
|
|
SPUNLOCK2(&lock);
|
|
ASSERT(0, lock);
|
|
|
|
x = 0;
|
|
y = 7;
|
|
ASSERT(0, x);
|
|
ASSERT(7, y);
|
|
__atomic_store(&x, &y, __ATOMIC_RELAXED);
|
|
ASSERT(7, x);
|
|
ASSERT(7, y);
|
|
|
|
x = 0;
|
|
y = 7;
|
|
ASSERT(0, x);
|
|
ASSERT(7, y);
|
|
__atomic_store(&x, &y, __ATOMIC_SEQ_CST);
|
|
ASSERT(7, x);
|
|
ASSERT(7, y);
|
|
|
|
x = 5;
|
|
y = __atomic_test_and_set(&x, __ATOMIC_SEQ_CST);
|
|
ASSERT(1, x);
|
|
ASSERT(5, y);
|
|
|
|
x = 5;
|
|
__atomic_clear(&x, __ATOMIC_SEQ_CST);
|
|
ASSERT(0, x);
|
|
|
|
//
|
|
}
|