@@ -98,9 +98,9 @@ __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
LIBC_PROBE (wrlock_entry, 1, rwlock);
if (ELIDE_LOCK (rwlock->__data.__rwelision,
- rwlock->__data.__lock == 0
- && rwlock->__data.__writer == 0
- && rwlock->__data.__nr_readers == 0))
+ rwlock->__data.__lock,
+ rwlock->__data.__writer,
+ rwlock->__data.__nr_readers))
@@ -15,11 +15,12 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+
#ifndef ELIDE_H
#define ELIDE_H 1
-#define ELIDE_LOCK(adapt_count, is_lock_free) 0
-#define ELIDE_TRYLOCK(adapt_count, is_lock_free, write) 0
-#define ELIDE_UNLOCK(is_lock_free) 0
+#define ELIDE_LOCK(adapt_count, lock, writer, readers) 0
+#define ELIDE_TRYLOCK(adapt_count, lock, writer, readers, write) 0
+#define ELIDE_UNLOCK(writer, readers) 0
#endif
@@ -27,7 +27,7 @@
ADAPT_COUNT is a pointer to per-lock state variable. */
static inline bool
-__elide_lock (uint8_t *adapt_count, int is_lock_free)
+__elide_lock (uint8_t *adapt_count, int *lock, int *writer, unsigned int *readers)
{
if (*adapt_count > 0)
{
@@ -39,7 +39,10 @@ __elide_lock (uint8_t *adapt_count, int is_lock_free)
{
if (__builtin_tbegin (0))
{
- if (is_lock_free)
+ /* The compiler barrier is required because some GCC version might
+ reorder the lock read before the transaction init builtin. */
+ asm volatile("" ::: "memory");
+ if ((*lock == 0) && (*writer == 0) && (*readers == 0))
return true;
/* Lock was busy. */
__builtin_tabort (_ABORT_LOCK_BUSY);
@@ -66,30 +69,31 @@ __elide_lock (uint8_t *adapt_count, int is_lock_free)
return false;
}
I do not know which is better, since it will tie the ELIDE_LOCK implementation
with current internal pthread definitions.