40 #ifndef GEOGRAM_BASIC_THREAD_SYNC
41 #define GEOGRAM_BASIC_THREAD_SYNC
61 #pragma intrinsic(_InterlockedCompareExchange16)
62 #pragma intrinsic(_WriteBarrier)
67 #if defined(__clang__)
68 #pragma GCC diagnostic ignored "-Wbraced-scalar-init"
79 # ifdef GEO_PROCESSOR_X86
83 __builtin_ia32_pause();
104 # define GEOGRAM_SPINLOCK_INIT 0
106 while(_InterlockedCompareExchange16(&x, 1, 0) == 1) {
141 #define GEOGRAM_SPINLOCK_INIT ATOMIC_FLAG_INIT
157 if (!x.test_and_set(std::memory_order_acquire)) {
162 #if defined(__cpp_lib_atomic_flag_test)
163 while (x.test(std::memory_order_relaxed))
174 x.clear(std::memory_order_release);
236 for(
index_t i=0; i<size_; ++i) {
246 spinlocks_ =
nullptr;
342 if(size_ != size_in) {
344 index_t nb_words = (size_ >> 5) + 1;
346 spinlocks_ =
new std::atomic<uint32_t>[nb_words];
347 for(
index_t i=0; i<nb_words; ++i) {
352 std::atomic_init(&spinlocks_[i],0u);
357 #ifdef __cpp_lib_atomic_is_always_lock_free
358 static_assert(std::atomic<uint32_t>::is_always_lock_free);
391 uint32_t b = uint32_t(i & 31);
392 uint32_t mask = (1u << b);
394 (spinlocks_[w].fetch_or(
395 mask, std::memory_order_acquire
410 uint32_t b = uint32_t(i & 31);
411 uint32_t mask = ~(1u << b);
412 spinlocks_[w].fetch_and(mask, std::memory_order_release);
418 std::atomic<uint32_t>* spinlocks_;
429 typedef CompactSpinLockArray SpinLockArray;
A function to suppress unused parameters compilation warnings.
Assertion checking mechanism.
#define geo_debug_assert(x)
Verifies that a condition is met.
An array of light-weight synchronisation primitives (spinlocks).
void clear()
Resets size to 0 and clears all the memory.
void resize(index_t size_in)
Resizes a BasicSpinLockArray.
void acquire_spinlock(index_t i)
Acquires a spinlock at a given index.
BasicSpinLockArray(index_t size_in)
Constructs a new BasicSpinLockArray of size size_in.
BasicSpinLockArray & operator=(const BasicSpinLockArray &rhs)=delete
Forbids copy.
BasicSpinLockArray(const BasicSpinLockArray &rhs)=delete
Forbids copy.
index_t size() const
Gets the number of spinlocks in this array.
void release_spinlock(index_t i)
Releases a spinlock at a given index.
BasicSpinLockArray()
Constructs a new BasicSpinLockArray of size 0.
An array of light-weight synchronisation primitives (spinlocks).
void resize(index_t size_in)
Resizes a CompactSpinLockArray.
void clear()
Resets size to 0 and clears all the memory.
CompactSpinLockArray(index_t size_in)
Constructs a new CompactSpinLockArray of size size_in.
CompactSpinLockArray(const CompactSpinLockArray &rhs)=delete
Forbids copy.
~CompactSpinLockArray()
CompactSpinLockArray destructor.
void release_spinlock(index_t i)
Releases a spinlock at a given index.
CompactSpinLockArray & operator=(const CompactSpinLockArray &rhs)=delete
Forbids copy.
void acquire_spinlock(index_t i)
Acquires a spinlock at a given index.
index_t size() const
Gets the number of spinlocks in this array.
CompactSpinLockArray()
Constructs a new SpinLockArray of size 0.
Common include file, providing basic definitions. Should be included before anything else by all head...
std::atomic_flag spinlock
A lightweight synchronization structure.
void release_spinlock(volatile spinlock &x)
Makes x available to other threads.
void acquire_spinlock(volatile spinlock &x)
Loops until x is available then reserves it.
Global Vorpaline namespace.
geo_index_t index_t
The type for storing and manipulating indices.
Types and functions for numbers manipulation.
void geo_pause()
executes the pause instruction