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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #define STATUS_AVAILABE 0 #define STATUS_READER 1 #define STATUS_WRITER 2 typedef struct { volatile int status; volatile int nr_readers; spinlock_t sl; } rwlock_t; void init_lock(rwlock_t *lock) { lock->status = STATUS_AVAILABE; lock->nr_readers = 0; spin_lock_init(&lock->sl); } void reader_lock(rwlock_t *lock) { while (TRUE) { while (lock->status == STATUS_WRITER) cpu_relax(); spin_lock(&lock->sl); if (lock->status != STATUS_WRITER) { if (lock->status == STATUS_AVAILABE) lock->status = STATUS_READER; lock->nr_readers++; spin_unlock(&lock->sl); return; } spin_unlock(&lock->sl); } } void reader_unlock(rwlock_t *lock) { spin_lock(&lock->sl); if (--lock->nr_readers == 0) lock->status = STATUS_AVAILABE; spin_unlock(&lock->sl); } void writer_lock(rwlock_t *lock) { while (TRUE) { while (lock->status != STATUS_AVAILABE) cpu_relax(); spin_lock(&lock->sl); if (lock->status == STATUS_ AVAILABE) { lock->status = STATUS_WRITER; spin_unlock(&lock->sl); return; } spin_unlock(&lock->sl); } } void writer_unlock(rwlock_t *lock) { spin_lock(&lock->sl); lock->status = STATUS_AVAILABE; //(a) spin_unlock(&lock->sl); } |
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 | #define WAFLAG 1 #define RC_INCR 2 typedef struct { atomic_t rdr_cnt_and_flag; } rwlock_t; void init_lock(rwlock_t *lock) { lock->rdr_cnt_and_flag = ATOMIC_INIT(0); //(a) } void reader_lock(rwlock_t *lock) { atomic_add(RC_INCR, &lock->rdr_cnt_and_flag); //(b) while ((atomic_read(&lock->rdr_cnt_and_flag) & WAFLAG) != 0) //(c) cpu_relax(); } void reader_unlock(rwlock_t *lock) { atomic_sub(RC_INCR, &lock->rdr_cnt_and_flag); //(d) } void writer_lock(rwlock_t *lock) { while (atomic_cmpxchg(&lock->rdr_cnt_and_flag, 0, WAFLAG) != 0) //(e) while (atomic_read(&lock->rdr_cnt_and_flag) != 0) //(f) cpu_relax(); } void writer_unlock(rwlock_t *lock) { atomic_dec(&lock->rdr_cnt_and_flag); //(g) } |
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 | #define WAFLAG (int)0x80000000 #define RC_INCR 1 typedef struct { atomic_t rdr_cnt_and_flag; } rwlock_t; void init_lock(rwlock_t *lock) { lock->rdr_cnt_and_flag = ATOMIC_INIT(0); //(a) } static inline int my_atomic_inc_negative(atomic_t *v) { unsigned char c; asm volatile(LOCK_PREFIX "incl %0; sets %1" : "+m" (v->counter), "=qm" (c) : : "memory"); return c; } void reader_lock(rwlock_t *lock) { int sign = my_atomic_inc_negative(&lock->rdr_cnt_and_flag); //(b) if (sign) //(c) while (atomic_read(&lock->rdr_cnt_and_flag) < 0) //(d) cpu_relax(); } void reader_unlock(rwlock_t *lock) { atomic_dec(&lock->rdr_cnt_and_flag); //(e) } void writer_lock(rwlock_t *lock) { while (atomic_cmpxchg(&lock->rdr_cnt_and_flag, 0, WAFLAG) != 0) //(f) while (atomic_read(&lock->rdr_cnt_and_flag) != 0) //(g) cpu_relax(); } void writer_unlock(rwlock_t *lock) { atomic_add(-WAFLAG, &lock->rdr_cnt_and_flag); //(h) } |
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |