blob: f9952959a1f7ae81f5e1bc6c1eea55e38db56cc4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#pragma once
/*
Simple Reader/Writer lock. Lets unlimited readers through but a writer will lock exclusively
not meant for high-throughput uses
this is useful when writes are very infrequent
*/
#include <bfc/platform/types.h>
#include <windows.h>
typedef size_t simple_rwlock_t;
static const size_t simple_rwlock_writer_active = 1; // writer active flag
static const size_t simple_rwlock_reader_increment= 2; // to adjust reader count
static inline void simple_rwlock_write_lock(simple_rwlock_t *lock)
{
while (InterlockedCompareExchangePointer((PVOID volatile*)lock, (PVOID)simple_rwlock_writer_active, 0))
{
// nop
}
}
static inline void simple_rwlock_write_unlock(simple_rwlock_t *lock)
{
#ifdef _WIN64
InterlockedExchangeAdd64((LONGLONG volatile*)lock, -simple_rwlock_writer_active);
#else
InterlockedExchangeAdd((LONG volatile*)lock, -simple_rwlock_writer_active);
#endif
}
static inline void simple_rwlock_read_lock(simple_rwlock_t *lock)
{
InterlockedExchangeAdd((LONG volatile*)lock, simple_rwlock_reader_increment);
while ((*lock & simple_rwlock_writer_active))
{
// nope
}
}
static inline void simple_rwlock_read_unlock(simple_rwlock_t *lock)
{
#ifdef _WIN64
InterlockedExchangeAdd64((LONGLONG volatile*)lock, -simple_rwlock_reader_increment);
#else
InterlockedExchangeAdd((LONG volatile*)lock, -simple_rwlock_reader_increment);
#endif
}
|