simple_rwlock.h 1.3 KB

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