|
51 | 51 | #endif
|
52 | 52 | static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1;
|
53 | 53 |
|
54 |
| -#ifndef CACHE_LINE_SIZE |
55 |
| -#define CACHE_LINE_SIZE 64 |
56 |
| -#endif |
57 |
| - |
58 |
| -#ifdef __clang__ |
59 |
| -#pragma clang diagnostic ignored "-Wgnu-designator" |
60 |
| -#endif |
61 |
| - |
62 | 54 | ////////////////////////////////////////////////////////////////////////////////
|
63 | 55 | // Platform-specific lock implementation. Falls back to spinlocks if none is
|
64 | 56 | // defined. Each platform should define the Lock type, and corresponding
|
@@ -102,18 +94,21 @@ static Lock locks[SPINLOCK_COUNT]; // initialized to OS_SPINLOCK_INIT which is 0
|
102 | 94 | #else
|
103 | 95 | _Static_assert(__atomic_always_lock_free(sizeof(uintptr_t), 0),
|
104 | 96 | "Implementation assumes lock-free pointer-size cmpxchg");
|
105 |
| -#include <pthread.h> |
106 |
| -#include <stdalign.h> |
107 |
| -typedef struct { |
108 |
| - alignas(CACHE_LINE_SIZE) pthread_mutex_t m; |
109 |
| -} Lock; |
| 97 | +typedef _Atomic(uintptr_t) Lock; |
110 | 98 | /// Unlock a lock. This is a release operation.
|
111 |
| -__inline static void unlock(Lock *l) { pthread_mutex_unlock(&l->m); } |
112 |
| -/// Locks a lock. |
113 |
| -__inline static void lock(Lock *l) { pthread_mutex_lock(&l->m); } |
| 99 | +__inline static void unlock(Lock *l) { |
| 100 | + __c11_atomic_store(l, 0, __ATOMIC_RELEASE); |
| 101 | +} |
| 102 | +/// Locks a lock. In the current implementation, this is potentially |
| 103 | +/// unbounded in the contended case. |
| 104 | +__inline static void lock(Lock *l) { |
| 105 | + uintptr_t old = 0; |
| 106 | + while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE, |
| 107 | + __ATOMIC_RELAXED)) |
| 108 | + old = 0; |
| 109 | +} |
114 | 110 | /// locks for atomic operations
|
115 |
| -static Lock locks[SPINLOCK_COUNT] = { |
116 |
| - [0 ... SPINLOCK_COUNT - 1] = {PTHREAD_MUTEX_INITIALIZER}}; |
| 111 | +static Lock locks[SPINLOCK_COUNT]; |
117 | 112 | #endif
|
118 | 113 |
|
119 | 114 | /// Returns a lock to use for a given pointer.
|
|
0 commit comments