oops forgot this
This commit is contained in:
parent
5d6734be4a
commit
65af565668
63
lrwl.h
Normal file
63
lrwl.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma omp
|
||||||
|
|
||||||
|
#define LRWL_WRITE_ACTIVE (1UL<<31)
|
||||||
|
#define LRWL_MASK (LRWL_WRITE_ACTIVE - 1)
|
||||||
|
#define LRWL_MAX_READERS 1024
|
||||||
|
|
||||||
|
typedef struct LRWL {
|
||||||
|
_Atomic uint32_t data;
|
||||||
|
} LRWL;
|
||||||
|
|
||||||
|
static inline void lrwl_read_lock(LRWL *self) {
|
||||||
|
while(1) {
|
||||||
|
uint32_t data = atomic_load(&self->data);
|
||||||
|
|
||||||
|
if((data & LRWL_WRITE_ACTIVE) || (data & LRWL_MASK) >= LRWL_MAX_READERS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(atomic_compare_exchange_weak(&self->data, &data, data + 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lrwl_read_unlock(LRWL *self) {
|
||||||
|
while(1) {
|
||||||
|
uint32_t data = atomic_load(&self->data);
|
||||||
|
|
||||||
|
assert((data & LRWL_MASK) > 0);
|
||||||
|
|
||||||
|
if(atomic_compare_exchange_weak(&self->data, &data, data - 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lrwl_write_lock(LRWL *self) {
|
||||||
|
while(1) {
|
||||||
|
uint32_t data = atomic_load(&self->data);
|
||||||
|
|
||||||
|
if(data & LRWL_WRITE_ACTIVE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(atomic_compare_exchange_weak(&self->data, &data, data | LRWL_WRITE_ACTIVE)) {
|
||||||
|
while((atomic_load(&self->data) & LRWL_MASK) > 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lrwl_write_unlock(LRWL *self) {
|
||||||
|
while(1) {
|
||||||
|
uint32_t data = atomic_load(&self->data);
|
||||||
|
|
||||||
|
assert(data & LRWL_WRITE_ACTIVE);
|
||||||
|
|
||||||
|
if(atomic_compare_exchange_weak(&self->data, &data, data & ~LRWL_WRITE_ACTIVE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user