From a332c46a51f9b4e13963340dfee1318e7513c124 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 31 Jan 2018 06:52:17 -0800 Subject: session: segment manager refactor - use valloc as a 'central' segment baseva manager - use per segment manager segment pools and use rwlocks to guard them - add session test that exercises segment creation - embed segment manager properties into application since they're shared - fix rw locks Change-Id: I761164c147275d9e8a926f1eda395e090d231f9a Signed-off-by: Florin Coras --- src/vppinfra/lock.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/vppinfra') diff --git a/src/vppinfra/lock.h b/src/vppinfra/lock.h index 0ffb0455be0..dd79c40b7f2 100644 --- a/src/vppinfra/lock.h +++ b/src/vppinfra/lock.h @@ -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; @@ -137,23 +138,39 @@ 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 (__sync_lock_test_and_set (&(*p)->n_readers_lock, 1)) + CLIB_PAUSE (); + + (*p)->n_readers += 1; + if ((*p)->n_readers == 1) { while (__sync_lock_test_and_set (&(*p)->writer_lock, 1)) 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 (__sync_lock_test_and_set (&(*p)->n_readers_lock, 1)) + 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 -- cgit 1.2.3-korg