* tst-initializers1.c: Show through exit code which test failed.
* pthread_rwlock_init.c: Also initialize __shared field.
* sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Split __flags
element in rwlock structure into four byte elements. One of them is
the new __shared element.
* sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h [__WORDSIZE=32]:
Likewise.
[__WORDSIZE=64]: Renamed __pad1 element int rwlock structire to
__shared, adjust names of other padding elements.
* sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
* sysdeps/pthread/pthread.h: Adjust rwlock initializers.
* sysdeps/unix/sysv/linux/lowlevelrwlock.sym: Add PSHARED.
* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define
FUTEX_PRIVATE_FLAG.
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Change main
futex to use private operations if possible.
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+2007-05-27 Ulrich Drepper <drepper@redhat.com>
+
+ * init.c: Make it compile with older kernel headers.
+
+ * tst-initializers1.c: Show through exit code which test failed.
+
+ * pthread_rwlock_init.c: Also initialize __shared field.
+ * sysdeps/unix/sysv/linux/i386/bits/pthreadtypes.h: Split __flags
+ element in rwlock structure into four byte elements. One of them is
+ the new __shared element.
+ * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h [__WORDSIZE=32]:
+ Likewise.
+ [__WORDSIZE=64]: Renamed __pad1 element int rwlock structire to
+ __shared, adjust names of other padding elements.
+ * sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h: Likewise.
+ * sysdeps/pthread/pthread.h: Adjust rwlock initializers.
+ * sysdeps/unix/sysv/linux/lowlevelrwlock.sym: Add PSHARED.
+ * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Define
+ FUTEX_PRIVATE_FLAG.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S: Change main
+ futex to use private operations if possible.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S: Likewise.
+
2007-05-26 Ulrich Drepper <drepper@redhat.com>
* pthreadP.h (PTHREAD_RWLOCK_PREFER_READER_P): Define.
__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
#endif
-#ifdef THREAD_COPY_PRIVATE_FUTEX
/* The thread must know when private futexes are supported. */
- THREAD_COPY_PRIVATE_FUTEX (pd);
-#endif
+ pd->header.private_futex = THREAD_GETMEM (THREAD_SELF,
+ header.private_futex);
#ifdef NEED_DL_SYSINFO
/* Copy the sysinfo value from the parent. */
#endif
set_robust_list_not_avail ();
-#ifdef THREAD_SET_PRIVATE_FUTEX
+#ifndef __ASSUME_PRIVATE_FUTEX
/* Private futexes are always used (at least internally) so that
doing the test once this early is beneficial. */
{
int word;
- res = INTERNAL_SYSCALL (futex, err, 3, &word,
+ word = INTERNAL_SYSCALL (futex, err, 3, &word,
FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
- if (!INTERNAL_SYSCALL_ERROR_P (res, err))
- pd->header.private_futex = FUTEX_PRIVATE_FLAG;
+ if (!INTERNAL_SYSCALL_ERROR_P (word, err))
+ THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
}
#endif
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
02111-1307 USA. */
#include "pthreadP.h"
+#include <kernel-features.h>
static const struct pthread_rwlockattr default_attr =
iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr;
rwlock->__data.__lock = 0;
- rwlock->__data.__flags
- = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
rwlock->__data.__nr_readers = 0;
- rwlock->__data.__writer = 0;
rwlock->__data.__readers_wakeup = 0;
rwlock->__data.__writer_wakeup = 0;
rwlock->__data.__nr_readers_queued = 0;
rwlock->__data.__nr_writers_queued = 0;
+ rwlock->__data.__writer = 0;
+
+ rwlock->__data.__flags
+ = iattr->lockkind == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
+
+ /* The __SHARED field is computed to minimize the work that needs to
+ be done while handling the futex. There are two inputs: the
+ availability of private futexes and whether the rwlock is shared
+ or private. Unfortunately the value of a private rwlock is
+ fixed: it must be zero. The PRIVATE_FUTEX flag has the value
+ 0x80 in case private futexes are available and zero otherwise.
+ This leads to the following table:
+
+ | pshared | result
+ | shared private | shared private |
+ ------------+-----------------+-----------------+
+ !avail 0 | 0 0 | 0 0 |
+ avail 0x80 | 0x80 0 | 0 0x80 |
+
+ If the pshared value is in locking functions XORed with avail
+ we get the expected result. */
+#ifdef __ASSUME_PRIVATE_FUTEX
+ rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+ ? 0 : FUTEX_PRIVATE_FLAG);
+#else
+ rwlock->__data.__shared = (iattr->pshared == PTHREAD_PROCESS_PRIVATE
+ ? 0
+ : THREAD_GETMEM (THREAD_SELF,
+ header.private_futex));
+#endif
+
+ rwlock->__data.__pad1 = 0;
+ rwlock->__data.__pad2 = 0;
return 0;
}
#define _PTHREAD_H 1
#include <features.h>
+#include <endian.h>
#include <sched.h>
#include <time.h>
};
/* Read-write lock initializers. */
-# if __WORDSIZE == 64
-# define PTHREAD_RWLOCK_INITIALIZER \
+# define PTHREAD_RWLOCK_INITIALIZER \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-# else
-# define PTHREAD_RWLOCK_INITIALIZER \
- { { 0, 0, 0, 0, 0, 0, 0, 0 } }
-# endif
# ifdef __USE_GNU
# if __WORDSIZE == 64
# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
# else
-# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
- { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 0 } }
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, \
+ 0, 0, 0, 0 } }
+# else
+# define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,\
+ 0 } }
+# endif
# endif
# endif
#endif /* Unix98 or XOpen2K */
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
int __writer;
} __data;
char __size[__SIZEOF_PTHREAD_RWLOCK_T];
#include <stddef.h>
#include <stdio.h>
#include <bits/pthreadtypes.h>
+#include <bits/wordsize.h>
--
WRITERS_QUEUED offsetof (pthread_rwlock_t, __data.__nr_writers_queued)
FLAGS offsetof (pthread_rwlock_t, __data.__flags)
WRITER offsetof (pthread_rwlock_t, __data.__writer)
+PSHARED offsetof (pthread_rwlock_t, __data.__shared)
/* Machine-specific pthread type layouts. PowerPC version.
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003.
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
int __writer;
} __data;
# endif
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
+#define FUTEX_PRIVATE_FLAG 128
+
/* Initializer for compatibility lock. */
#define LLL_MUTEX_LOCK_INITIALIZER (0)
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
unsigned int __nr_writers_queued;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
+ unsigned char __shared;
+ unsigned char __pad1;
+ unsigned char __pad2;
int __writer;
} __data;
# endif
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5: movl $0, WRITER(%rdi)
- movl $1, %esi
leaq WRITERS_WAKEUP(%rdi), %r10
movq %rsi, %rdx
cmpl $0, WRITERS_QUEUED(%rdi)
#endif
jne 7f
-8: movl $SYS_futex, %eax
+8:
+#if __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %esi
+ xorl PSHARED(%rdi), %esi
+#else
+ movl $FUTEX_WAKE, %esi
+ orl PSHARED(%rdi), %esi
+ xorl %fs:PRIVATE_FUTEX, %esi
+#endif
+ movl $SYS_futex, %eax
movq %r10, %rdi
syscall
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
if (mtx_normal.__data.__kind != PTHREAD_MUTEX_TIMED_NP)
return 1;
if (mtx_recursive.__data.__kind != PTHREAD_MUTEX_RECURSIVE_NP)
- return 1;
+ return 2;
if (mtx_errorchk.__data.__kind != PTHREAD_MUTEX_ERRORCHECK_NP)
- return 1;
+ return 3;
if (mtx_adaptive.__data.__kind != PTHREAD_MUTEX_ADAPTIVE_NP)
- return 1;
+ return 4;
if (rwl_normal.__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
- return 1;
+ return 5;
if (rwl_writer.__data.__flags
!= PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
- return 1;
+ return 6;
return 0;
}