rwlock.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #ifndef SKYNET_RWLOCK_H
  2. #define SKYNET_RWLOCK_H
  3. #ifndef USE_PTHREAD_LOCK
  4. #include "atomic.h"
  5. struct rwlock {
  6. ATOM_INT write;
  7. ATOM_INT read;
  8. };
  9. static inline void
  10. rwlock_init(struct rwlock *lock) {
  11. ATOM_INIT(&lock->write, 0);
  12. ATOM_INIT(&lock->read, 0);
  13. }
  14. static inline void
  15. rwlock_rlock(struct rwlock *lock) {
  16. for (;;) {
  17. while(ATOM_LOAD(&lock->write)) {}
  18. ATOM_FINC(&lock->read);
  19. if (ATOM_LOAD(&lock->write)) {
  20. ATOM_FDEC(&lock->read);
  21. } else {
  22. break;
  23. }
  24. }
  25. }
  26. static inline void
  27. rwlock_wlock(struct rwlock *lock) {
  28. while (!ATOM_CAS(&lock->write,0,1)) {}
  29. while(ATOM_LOAD(&lock->read)) {}
  30. }
  31. static inline void
  32. rwlock_wunlock(struct rwlock *lock) {
  33. ATOM_STORE(&lock->write, 0);
  34. }
  35. static inline void
  36. rwlock_runlock(struct rwlock *lock) {
  37. ATOM_FDEC(&lock->read);
  38. }
  39. #else
  40. #include <pthread.h>
  41. // only for some platform doesn't have __sync_*
  42. // todo: check the result of pthread api
  43. struct rwlock {
  44. pthread_rwlock_t lock;
  45. };
  46. static inline void
  47. rwlock_init(struct rwlock *lock) {
  48. pthread_rwlock_init(&lock->lock, NULL);
  49. }
  50. static inline void
  51. rwlock_rlock(struct rwlock *lock) {
  52. pthread_rwlock_rdlock(&lock->lock);
  53. }
  54. static inline void
  55. rwlock_wlock(struct rwlock *lock) {
  56. pthread_rwlock_wrlock(&lock->lock);
  57. }
  58. static inline void
  59. rwlock_wunlock(struct rwlock *lock) {
  60. pthread_rwlock_unlock(&lock->lock);
  61. }
  62. static inline void
  63. rwlock_runlock(struct rwlock *lock) {
  64. pthread_rwlock_unlock(&lock->lock);
  65. }
  66. #endif
  67. #endif