X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Flock.h;h=337c5a3f0ad4bc5ca60cd04818afdeef05c4b8ef;hb=040950a59d53e8802ad31430d67df105939cce4c;hp=0ffb0455be051a780be017dfe086fa056f50a83c;hpb=1f9600e50f3317e8a9abd5ac38734010ca08e246;p=vpp.git diff --git a/src/vppinfra/lock.h b/src/vppinfra/lock.h index 0ffb0455be0..337c5a3f0ad 100644 --- a/src/vppinfra/lock.h +++ b/src/vppinfra/lock.h @@ -57,7 +57,7 @@ static inline void clib_spinlock_init (clib_spinlock_t * p) { *p = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES); - memset ((void *) *p, 0, CLIB_CACHE_LINE_BYTES); + clib_memset ((void *) *p, 0, CLIB_CACHE_LINE_BYTES); } static inline void @@ -73,7 +73,7 @@ clib_spinlock_free (clib_spinlock_t * p) static_always_inline void clib_spinlock_lock (clib_spinlock_t * p) { - while (__sync_lock_test_and_set (&(*p)->lock, 1)) + while (clib_atomic_test_and_set (&(*p)->lock)) CLIB_PAUSE (); CLIB_LOCK_DBG (p); } @@ -109,6 +109,7 @@ typedef struct clib_rw_lock_ { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); volatile u32 n_readers; + volatile u32 n_readers_lock; volatile u32 writer_lock; #if CLIB_DEBUG > 0 pid_t pid; @@ -121,7 +122,7 @@ always_inline void clib_rwlock_init (clib_rwlock_t * p) { *p = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES); - memset ((void *) *p, 0, CLIB_CACHE_LINE_BYTES); + clib_memset ((void *) *p, 0, CLIB_CACHE_LINE_BYTES); } always_inline void @@ -137,29 +138,45 @@ clib_rwlock_free (clib_rwlock_t * p) always_inline void clib_rwlock_reader_lock (clib_rwlock_t * p) { - if (__sync_fetch_and_add (&(*p)->n_readers, 1) == 0) + while (clib_atomic_test_and_set (&(*p)->n_readers_lock)) + CLIB_PAUSE (); + + (*p)->n_readers += 1; + if ((*p)->n_readers == 1) { - while (__sync_lock_test_and_set (&(*p)->writer_lock, 1)) + while (clib_atomic_test_and_set (&(*p)->writer_lock)) CLIB_PAUSE (); } + CLIB_MEMORY_BARRIER (); + (*p)->n_readers_lock = 0; + CLIB_LOCK_DBG (p); } always_inline void clib_rwlock_reader_unlock (clib_rwlock_t * p) { + ASSERT ((*p)->n_readers > 0); CLIB_LOCK_DBG_CLEAR (p); - if (__sync_fetch_and_sub (&(*p)->n_readers, 1) == 1) + + while (clib_atomic_test_and_set (&(*p)->n_readers_lock)) + CLIB_PAUSE (); + + (*p)->n_readers -= 1; + if ((*p)->n_readers == 0) { CLIB_MEMORY_BARRIER (); (*p)->writer_lock = 0; } + + CLIB_MEMORY_BARRIER (); + (*p)->n_readers_lock = 0; } always_inline void clib_rwlock_writer_lock (clib_rwlock_t * p) { - while (__sync_lock_test_and_set (&(*p)->writer_lock, 1)) + while (clib_atomic_test_and_set (&(*p)->writer_lock)) CLIB_PAUSE (); CLIB_LOCK_DBG (p); }