mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
87 lines
1.4 KiB
C
87 lines
1.4 KiB
C
#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
|