123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- #ifndef SKYNET_RWLOCK_H
- #define SKYNET_RWLOCK_H
- #ifndef USE_PTHREAD_LOCK
- #include "atomic.h"
- struct rwlock {
- ATOM_INT write;
- ATOM_INT read;
- };
- static inline void
- rwlock_init(struct rwlock *lock) {
- ATOM_INIT(&lock->write, 0);
- ATOM_INIT(&lock->read, 0);
- }
- static inline void
- rwlock_rlock(struct rwlock *lock) {
- for (;;) {
- while(ATOM_LOAD(&lock->write)) {}
- ATOM_FINC(&lock->read);
- if (ATOM_LOAD(&lock->write)) {
- ATOM_FDEC(&lock->read);
- } else {
- break;
- }
- }
- }
- static inline void
- rwlock_wlock(struct rwlock *lock) {
- while (!ATOM_CAS(&lock->write,0,1)) {}
- while(ATOM_LOAD(&lock->read)) {}
- }
- static inline void
- rwlock_wunlock(struct rwlock *lock) {
- ATOM_STORE(&lock->write, 0);
- }
- static inline void
- rwlock_runlock(struct rwlock *lock) {
- ATOM_FDEC(&lock->read);
- }
- #else
- #include <pthread.h>
- // only for some platform doesn't have __sync_*
- // todo: check the result of pthread api
- struct rwlock {
- pthread_rwlock_t lock;
- };
- static inline void
- rwlock_init(struct rwlock *lock) {
- pthread_rwlock_init(&lock->lock, NULL);
- }
- static inline void
- rwlock_rlock(struct rwlock *lock) {
- pthread_rwlock_rdlock(&lock->lock);
- }
- static inline void
- rwlock_wlock(struct rwlock *lock) {
- pthread_rwlock_wrlock(&lock->lock);
- }
- static inline void
- rwlock_wunlock(struct rwlock *lock) {
- pthread_rwlock_unlock(&lock->lock);
- }
- static inline void
- rwlock_runlock(struct rwlock *lock) {
- pthread_rwlock_unlock(&lock->lock);
- }
- #endif
- #endif
|