diff options
Diffstat (limited to 'nptl/pthread_rwlock_wrlock.c')
-rw-r--r-- | nptl/pthread_rwlock_wrlock.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c index 1613d4507c..de54e51432 100644 --- a/nptl/pthread_rwlock_wrlock.c +++ b/nptl/pthread_rwlock_wrlock.c @@ -25,29 +25,15 @@ /* Acquire write lock for RWLOCK. */ -int -__pthread_rwlock_wrlock (rwlock) - pthread_rwlock_t *rwlock; +static int __attribute__((noinline)) +__pthread_rwlock_wrlock_slow (pthread_rwlock_t *rwlock) { int result = 0; - LIBC_PROBE (wrlock_entry, 1, rwlock); - - /* Make sure we are alone. */ - lll_lock (rwlock->__data.__lock, rwlock->__data.__shared); + /* Caller has taken the lock. */ while (1) { - /* Get the rwlock if there is no writer and no reader. */ - if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0) - { - /* Mark self as writer. */ - rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid); - - LIBC_PROBE (wrlock_acquire_write, 1, rwlock); - break; - } - /* Make sure we are not holding the rwlock as a writer. This is a deadlock situation we recognize and report. */ if (__builtin_expect (rwlock->__data.__writer @@ -80,6 +66,16 @@ __pthread_rwlock_wrlock (rwlock) /* To start over again, remove the thread from the writer list. */ --rwlock->__data.__nr_writers_queued; + + /* Get the rwlock if there is no writer and no reader. */ + if (rwlock->__data.__writer == 0 && rwlock->__data.__nr_readers == 0) + { + /* Mark self as writer. */ + rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid); + + LIBC_PROBE (wrlock_acquire_write, 1, rwlock); + break; + } } /* We are done, free the lock. */ @@ -88,5 +84,34 @@ __pthread_rwlock_wrlock (rwlock) return result; } +/* Fast path of acquiring write lock for RWLOCK. */ + +int +__pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) +{ + LIBC_PROBE (wrlock_entry, 1, rwlock); + + /* Make sure we are alone. */ + lll_lock (rwlock->__data.__lock, rwlock->__data.__shared); + + /* Get the rwlock if there is no writer and no reader. */ + if (__glibc_likely((rwlock->__data.__writer | + rwlock->__data.__nr_readers) == 0)) + { + /* Mark self as writer. */ + rwlock->__data.__writer = THREAD_GETMEM (THREAD_SELF, tid); + + LIBC_PROBE (wrlock_acquire_write, 1, rwlock); + + /* We are done, free the lock. */ + lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared); + + return 0; + } + + return __pthread_rwlock_wrlock_slow (rwlock); +} + + weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock) hidden_def (__pthread_rwlock_wrlock) |