summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/ldsodefs.h1
-rw-r--r--sysdeps/generic/rtld-lowlevel.h1
-rw-r--r--sysdeps/generic/unsecvars.h1
-rw-r--r--sysdeps/i386/i486/bits/atomic.h370
-rw-r--r--sysdeps/mach/hurd/futimes.c18
-rw-r--r--sysdeps/mach/hurd/lutimes.c17
-rw-r--r--sysdeps/mach/hurd/utimes.c19
-rw-r--r--sysdeps/posix/getaddrinfo.c10
-rw-r--r--sysdeps/unix/sysv/linux/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/i386/sysdep.h2
-rw-r--r--sysdeps/unix/sysv/linux/sys/epoll.h20
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list1
-rw-r--r--sysdeps/x86_64/bits/atomic.h334
13 files changed, 580 insertions, 217 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index b7d0f9b7e7..e9198bca05 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -38,6 +38,7 @@
#include <bits/libc-lock.h>
#include <hp-timing.h>
#include <tls.h>
+#include <rtld-lowlevel.h>
__BEGIN_DECLS
diff --git a/sysdeps/generic/rtld-lowlevel.h b/sysdeps/generic/rtld-lowlevel.h
new file mode 100644
index 0000000000..353fad28d4
--- /dev/null
+++ b/sysdeps/generic/rtld-lowlevel.h
@@ -0,0 +1 @@
+#error "Lowlevel primitives for ld.so not implemented"
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h
index a7378b742f..d5b8119c9c 100644
--- a/sysdeps/generic/unsecvars.h
+++ b/sysdeps/generic/unsecvars.h
@@ -18,6 +18,7 @@
"LOCALDOMAIN\0" \
"LOCPATH\0" \
"MALLOC_TRACE\0" \
+ "NIS_PATH\0" \
"NLSPATH\0" \
"RESOLV_HOST_CONF\0" \
"RES_OPTIONS\0" \
diff --git a/sysdeps/i386/i486/bits/atomic.h b/sysdeps/i386/i486/bits/atomic.h
index c748761758..a27734c37e 100644
--- a/sysdeps/i386/i486/bits/atomic.h
+++ b/sysdeps/i386/i486/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <stdint.h>
+#include <tls.h> /* For tcbhead_t. */
typedef int8_t atomic8_t;
@@ -76,6 +77,40 @@ typedef uintmax_t uatomic_max_t;
: "r" (newval), "m" (*mem), "0" (oldval)); \
ret; })
+
+#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgb %b2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
+#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgw %w2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
+#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "r" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
/* XXX We do not really need 64-bit compare-and-exchange. At least
not in the moment. Using it would mean causing portability
problems since not many other 32-bit architectures have support for
@@ -85,6 +120,8 @@ typedef uintmax_t uatomic_max_t;
#if 1
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
+# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret = *(mem); abort (); ret = (newval); ret = (oldval); })
#else
# ifdef __PIC__
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
@@ -100,6 +137,24 @@ typedef uintmax_t uatomic_max_t;
& 0xffffffff), \
"d" (((unsigned long long int) (oldval)) >> 32)); \
ret; })
+
+# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("xchgl %2, %%ebx\n\t" \
+ "cmpl $0, %%gs:%P7\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchg8b %1\n\t" \
+ "xchgl %2, %%ebx" \
+ : "=A" (ret), "=m" (*mem) \
+ : "DS" (((unsigned long long int) (newval)) \
+ & 0xffffffff), \
+ "c" (((unsigned long long int) (newval)) >> 32), \
+ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+ & 0xffffffff), \
+ "d" (((unsigned long long int) (oldval)) >> 32), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
# else
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __typeof (*mem) ret; \
@@ -112,6 +167,22 @@ typedef uintmax_t uatomic_max_t;
& 0xffffffff), \
"d" (((unsigned long long int) (oldval)) >> 32)); \
ret; })
+
+# define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%gs:%P7\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchg8b %1" \
+ : "=A" (ret), "=m" (*mem) \
+ : "b" (((unsigned long long int) (newval)) \
+ & 0xffffffff), \
+ "c" (((unsigned long long int) (newval)) >> 32), \
+ "m" (*mem), "a" (((unsigned long long int) (oldval)) \
+ & 0xffffffff), \
+ "d" (((unsigned long long int) (oldval)) >> 32), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
# endif
#endif
@@ -139,21 +210,24 @@ typedef uintmax_t uatomic_max_t;
result; })
-#define atomic_exchange_and_add(mem, value) \
+#define __arch_exchange_and_add_body(lock, pfx, mem, value) \
({ __typeof (*mem) __result; \
__typeof (value) __addval = (value); \
if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \
+ __asm __volatile (lock "xaddb %b0, %1" \
: "=r" (__result), "=m" (*mem) \
- : "0" (__addval), "m" (*mem)); \
+ : "0" (__addval), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \
+ __asm __volatile (lock "xaddw %w0, %1" \
: "=r" (__result), "=m" (*mem) \
- : "0" (__addval), "m" (*mem)); \
+ : "0" (__addval), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \
+ __asm __volatile (lock "xaddl %0, %1" \
: "=r" (__result), "=m" (*mem) \
- : "0" (__addval), "m" (*mem)); \
+ : "0" (__addval), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else \
{ \
__typeof (mem) __memp = (mem); \
@@ -161,41 +235,64 @@ typedef uintmax_t uatomic_max_t;
__result = *__memp; \
do \
__tmpval = __result; \
- while ((__result = __arch_compare_and_exchange_val_64_acq \
+ while ((__result = pfx##_compare_and_exchange_val_64_acq \
(__memp, __result + __addval, __result)) == __tmpval); \
} \
__result; })
+#define atomic_exchange_and_add(mem, value) \
+ __arch_exchange_and_add_body (LOCK_PREFIX, __arch, mem, value)
+
+#define __arch_exchange_and_add_cprefix \
+ "cmpl $0, %%gs:%P4\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_exchange_and_add(mem, value) \
+ __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, __arch_c, \
+ mem, value)
+
+
+#define __arch_add_body(lock, pfx, mem, value) \
+ do { \
+ if (__builtin_constant_p (value) && (value) == 1) \
+ atomic_increment (mem); \
+ else if (__builtin_constant_p (value) && (value) == -1) \
+ atomic_decrement (mem); \
+ else if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "addb %b1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "addw %w1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "addl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ { \
+ __typeof (value) __addval = (value); \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = pfx##_compare_and_exchange_val_64_acq \
+ (__memp, __oldval + __addval, __oldval)) == __tmpval); \
+ } \
+ } while (0)
#define atomic_add(mem, value) \
- (void) ({ if (__builtin_constant_p (value) && (value) == 1) \
- atomic_increment (mem); \
- else if (__builtin_constant_p (value) && (value) == -1) \
- atomic_decrement (mem); \
- else if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "addb %b1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "addw %w1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "addl %1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else \
- { \
- __typeof (value) __addval = (value); \
- __typeof (mem) __memp = (mem); \
- __typeof (*mem) __oldval = *__memp; \
- __typeof (*mem) __tmpval; \
- do \
- __tmpval = __oldval; \
- while ((__oldval = __arch_compare_and_exchange_val_64_acq \
- (__memp, __oldval + __addval, __oldval)) == __tmpval); \
- } \
- })
+ __arch_add_body (LOCK_PREFIX, __arch, mem, value)
+
+#define __arch_add_cprefix \
+ "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_add(mem, value) \
+ __arch_add_body (__arch_add_cprefix, __arch_c, mem, value)
#define atomic_add_negative(mem, value) \
@@ -236,30 +333,42 @@ typedef uintmax_t uatomic_max_t;
__result; })
-#define atomic_increment(mem) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "incb %b0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "incw %w0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "incl %0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else \
- { \
- __typeof (mem) __memp = (mem); \
- __typeof (*mem) __oldval = *__memp; \
- __typeof (*mem) __tmpval; \
- do \
- __tmpval = __oldval; \
- while ((__oldval = __arch_compare_and_exchange_val_64_acq \
- (__memp, __oldval + 1, __oldval)) == __tmpval); \
- } \
- })
+#define __arch_increment_body(lock, pfx, mem) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "incb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "incw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "incl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ { \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = pfx##_compare_and_exchange_val_64_acq \
+ (__memp, __oldval + 1, __oldval)) == __tmpval); \
+ } \
+ } while (0)
+
+#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, __arch, mem)
+
+#define __arch_increment_cprefix \
+ "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_increment(mem) \
+ __arch_increment_body (__arch_increment_cprefix, __arch_c, mem)
#define atomic_increment_and_test(mem) \
@@ -281,30 +390,42 @@ typedef uintmax_t uatomic_max_t;
__result; })
-#define atomic_decrement(mem) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "decb %b0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "decw %w0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "decl %0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else \
- { \
- __typeof (mem) __memp = (mem); \
- __typeof (*mem) __oldval = *__memp; \
- __typeof (*mem) __tmpval; \
- do \
- __tmpval = __oldval; \
- while ((__oldval = __arch_compare_and_exchange_val_64_acq \
- (__memp, __oldval - 1, __oldval)) == __tmpval); \
- } \
- })
+#define __arch_decrement_body(lock, pfx, mem) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "decb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "decw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "decl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ { \
+ __typeof (mem) __memp = (mem); \
+ __typeof (*mem) __oldval = *__memp; \
+ __typeof (*mem) __tmpval; \
+ do \
+ __tmpval = __oldval; \
+ while ((__oldval = pfx##_compare_and_exchange_val_64_acq \
+ (__memp, __oldval - 1, __oldval)) == __tmpval); \
+ } \
+ } while (0)
+
+#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, __arch, mem)
+
+#define __arch_decrement_cprefix \
+ "cmpl $0, %%gs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_decrement(mem) \
+ __arch_decrement_body (__arch_decrement_cprefix, __arch_c, mem)
#define atomic_decrement_and_test(mem) \
@@ -327,21 +448,22 @@ typedef uintmax_t uatomic_max_t;
#define atomic_bit_set(mem, bit) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1 << (bit))); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1 << (bit))); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "orl %2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1 << (bit))); \
- else \
- abort (); \
- })
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "orl %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1 << (bit))); \
+ else \
+ abort (); \
+ } while (0)
#define atomic_bit_test_set(mem, bit) \
@@ -364,3 +486,51 @@ typedef uintmax_t uatomic_max_t;
#define atomic_delay() asm ("rep; nop")
+
+
+#define atomic_and(mem, mask) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "andb %1, %b0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "andw %1, %w0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "andl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else \
+ abort (); \
+ } while (0)
+
+
+#define __arch_or_body(lock, mem, mask) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "orb %1, %b0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "orw %1, %w0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "orl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ abort (); \
+ } while (0)
+
+#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask)
+
+#define __arch_or_cprefix \
+ "cmpl $0, %%gs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask)
diff --git a/sysdeps/mach/hurd/futimes.c b/sysdeps/mach/hurd/futimes.c
index ca687b8bdf..4628eee2c3 100644
--- a/sysdeps/mach/hurd/futimes.c
+++ b/sysdeps/mach/hurd/futimes.c
@@ -1,5 +1,5 @@
/* futimes -- change access and modification times of open file. Hurd version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006 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
@@ -28,20 +28,24 @@
int
__futimes (int fd, const struct timeval tvp[2])
{
- struct timeval timevals[2];
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
error_t err;
if (tvp == NULL)
{
/* Setting the number of microseconds to `-1' tells the
underlying filesystems to use the current time. */
- timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
- tvp = timevals;
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
}
- err = HURD_DPORT_USE (fd, __file_utimes (port,
- *(time_value_t *) &tvp[0],
- *(time_value_t *) &tvp[1]));
+ err = HURD_DPORT_USE (fd, __file_utimes (port, u[0].tvt, u[1].tvt));
return err ? __hurd_dfail (fd, err) : 0;
}
weak_alias (__futimes, futimes)
diff --git a/sysdeps/mach/hurd/lutimes.c b/sysdeps/mach/hurd/lutimes.c
index cf89d8862f..bf5610c467 100644
--- a/sysdeps/mach/hurd/lutimes.c
+++ b/sysdeps/mach/hurd/lutimes.c
@@ -1,5 +1,5 @@
/* lutimes -- change access and modification times of a symlink. Hurd version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006 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
@@ -28,7 +28,13 @@
int
__lutimes (const char *file, const struct timeval tvp[2])
{
- struct timeval timevals[2];
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
error_t err;
file_t port;
@@ -36,15 +42,14 @@ __lutimes (const char *file, const struct timeval tvp[2])
{
/* Setting the number of microseconds to `-1' tells the
underlying filesystems to use the current time. */
- timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
- tvp = timevals;
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
}
port = __file_name_lookup (file, O_NOLINK, 0);
if (port == MACH_PORT_NULL)
return -1;
- err = __file_utimes (port,
- *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+ err = __file_utimes (port, u[0].tvt, u[1].tvt);
__mach_port_deallocate (__mach_task_self (), port);
if (err)
return __hurd_fail (err);
diff --git a/sysdeps/mach/hurd/utimes.c b/sysdeps/mach/hurd/utimes.c
index 74f3a342f4..fdc1427feb 100644
--- a/sysdeps/mach/hurd/utimes.c
+++ b/sysdeps/mach/hurd/utimes.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-1995, 97, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1995,1997,1999,2000,2006
+ 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
@@ -28,7 +29,13 @@ __utimes (file, tvp)
const char *file;
const struct timeval tvp[2];
{
- struct timeval timevals[2];
+ union tv
+ {
+ struct timeval tv;
+ time_value_t tvt;
+ };
+ const union tv *u = (const union tv *) tvp;
+ union tv nulltv[2];
error_t err;
file_t port;
@@ -36,19 +43,17 @@ __utimes (file, tvp)
{
/* Setting the number of microseconds to `-1' tells the
underlying filesystems to use the current time. */
- timevals[1].tv_usec = timevals[0].tv_usec = (time_t)-1;
- tvp = timevals;
+ nulltv[0].tvt.microseconds = nulltv[1].tvt.microseconds = -1;
+ u = nulltv;
}
port = __file_name_lookup (file, 0, 0);
if (port == MACH_PORT_NULL)
return -1;
- err = __file_utimes (port,
- *(time_value_t *) &tvp[0], *(time_value_t *) &tvp[1]);
+ err = __file_utimes (port, u[0].tvt, u[1].tvt);
__mach_port_deallocate (__mach_task_self (), port);
if (err)
return __hurd_fail (err);
return 0;
}
-
weak_alias (__utimes, utimes)
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 9387e20db2..84a6293365 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -1395,10 +1395,10 @@ rfc3484_sort (const void *p1, const void *p2)
{
if (!(a1->source_addr_flags & in6ai_homeaddress)
&& (a2->source_addr_flags & in6ai_homeaddress))
- return -1;
+ return 1;
if ((a1->source_addr_flags & in6ai_homeaddress)
&& !(a2->source_addr_flags & in6ai_homeaddress))
- return 1;
+ return -1;
}
/* Rule 5: Prefer matching label. */
@@ -1435,11 +1435,11 @@ rfc3484_sort (const void *p1, const void *p2)
if (a1->got_source_addr)
{
if (!(a1->source_addr_flags & in6ai_temporary)
- && (a1->source_addr_flags & in6ai_temporary))
+ && (a2->source_addr_flags & in6ai_temporary))
return -1;
if ((a1->source_addr_flags & in6ai_temporary)
- && !(a1->source_addr_flags & in6ai_temporary))
- return -1;
+ && !(a2->source_addr_flags & in6ai_temporary))
+ return 1;
/* XXX Do we need to check anything beside temporary addresses? */
}
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index 7c015b1d62..137b44c2b8 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -126,6 +126,9 @@ libc {
GLIBC_2.5 {
splice; sync_file_range; tee; vmsplice;
}
+ GLIBC_2.6 {
+ epoll_pwait;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__syscall_rt_sigqueueinfo;
diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h
index 90423d8434..5286676fc1 100644
--- a/sysdeps/unix/sysv/linux/i386/sysdep.h
+++ b/sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -297,7 +297,7 @@
cfi_restore (edi); L(POPDI1):
#define PUSHARGS_6 _PUSHARGS_6
-#define DOARGS_6 _DOARGS_6 (36)
+#define DOARGS_6 _DOARGS_6 (40)
#define POPARGS_6 _POPARGS_6
#define _PUSHARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
cfi_rel_offset (ebp, 0); L(PUSHBP1): _PUSHARGS_5
diff --git a/sysdeps/unix/sysv/linux/sys/epoll.h b/sysdeps/unix/sysv/linux/sys/epoll.h
index 68f173a04d..d8901f7d53 100644
--- a/sysdeps/unix/sysv/linux/sys/epoll.h
+++ b/sysdeps/unix/sysv/linux/sys/epoll.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 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
@@ -22,6 +22,14 @@
#include <stdint.h>
#include <sys/types.h>
+/* Get __sigset_t. */
+#include <bits/sigset.h>
+
+#ifndef __sigset_t_defined
+# define __sigset_t_defined
+typedef __sigset_t sigset_t;
+#endif
+
enum EPOLL_EVENTS
{
@@ -105,6 +113,16 @@ extern int epoll_ctl (int __epfd, int __op, int __fd,
extern int epoll_wait (int __epfd, struct epoll_event *__events,
int __maxevents, int __timeout);
+
+/* Same as epoll_wait, but the thread's signal mask is temporarily
+ and atomically replaced with the one provided as parameter.
+
+ This function is a cancellation point and therefore not marked with
+ __THROW. */
+extern int epoll_pwait (int __epfd, struct epoll_event *__events,
+ int __maxevents, int __timeout,
+ __const __sigset_t *__ss);
+
__END_DECLS
#endif /* sys/epoll.h */
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index fca29b26ff..5776673733 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -10,6 +10,7 @@ delete_module EXTRA delete_module 3 delete_module
epoll_create EXTRA epoll_create i:i epoll_create
epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl
epoll_wait EXTRA epoll_wait Ci:ipii epoll_wait
+epoll_pwait EXTRA epoll_pwait Ci:ipiipi epoll_pwait
fdatasync - fdatasync i:i fdatasync
flock - flock i:ii __flock flock
fork - fork i: __libc_fork __fork fork
diff --git a/sysdeps/x86_64/bits/atomic.h b/sysdeps/x86_64/bits/atomic.h
index 133a68d192..65d6b02008 100644
--- a/sysdeps/x86_64/bits/atomic.h
+++ b/sysdeps/x86_64/bits/atomic.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <stdint.h>
+#include <tls.h> /* For tcbhead_t. */
typedef int8_t atomic8_t;
@@ -80,8 +81,54 @@ typedef uintmax_t uatomic_max_t;
({ __typeof (*mem) ret; \
__asm __volatile (LOCK_PREFIX "cmpxchgq %q2, %1" \
: "=a" (ret), "=m" (*mem) \
- : "r" ((long) (newval)), "m" (*mem), \
- "0" ((long) (oldval))); \
+ : "r" ((long int) (newval)), "m" (*mem), \
+ "0" ((long int) (oldval))); \
+ ret; })
+
+
+#define __arch_c_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgb %b2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
+#define __arch_c_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgw %w2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
+#define __arch_c_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgl %2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" (newval), "m" (*mem), "0" (oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ ret; })
+
+#define __arch_c_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+ ({ __typeof (*mem) ret; \
+ __asm __volatile ("cmpl $0, %%fs:%P5\n\t" \
+ "je 0f\n\t" \
+ "lock\n" \
+ "0:\tcmpxchgq %q2, %1" \
+ : "=a" (ret), "=m" (*mem) \
+ : "q" ((long int) (newval)), "m" (*mem), \
+ "0" ((long int)oldval), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
ret; })
@@ -107,49 +154,76 @@ typedef uintmax_t uatomic_max_t;
result; })
-#define atomic_exchange_and_add(mem, value) \
+#define __arch_exchange_and_add_body(lock, mem, value) \
({ __typeof (*mem) result; \
if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "xaddb %b0, %1" \
+ __asm __volatile (lock "xaddb %b0, %1" \
: "=r" (result), "=m" (*mem) \
- : "0" (value), "m" (*mem)); \
+ : "0" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "xaddw %w0, %1" \
+ __asm __volatile (lock "xaddw %w0, %1" \
: "=r" (result), "=m" (*mem) \
- : "0" (value), "m" (*mem)); \
+ : "0" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "xaddl %0, %1" \
+ __asm __volatile (lock "xaddl %0, %1" \
: "=r" (result), "=m" (*mem) \
- : "0" (value), "m" (*mem)); \
+ : "0" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
else \
- __asm __volatile (LOCK_PREFIX "xaddq %q0, %1" \
+ __asm __volatile (lock "xaddq %q0, %1" \
: "=r" (result), "=m" (*mem) \
- : "0" ((long) (value)), "m" (*mem)); \
+ : "0" ((long) (value)), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
result; })
+#define atomic_exchange_and_add(mem, value) \
+ __arch_exchange_and_add_body (LOCK_PREFIX, mem, value)
+
+#define __arch_exchange_and_add_cprefix \
+ "cmpl $0, %%fs:%P4\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_exchange_and_add(mem, value) \
+ __arch_exchange_and_add_body (__arch_exchange_and_add_cprefix, mem, value)
+
+
+#define __arch_add_body(lock, pfx, mem, value) \
+ do { \
+ if (__builtin_constant_p (value) && (value) == 1) \
+ pfx##_increment (mem); \
+ else if (__builtin_constant_p (value) && (value) == -1) \
+ pfx##_decrement (mem); \
+ else if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "addb %b1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "addw %w1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "addl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (value), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ __asm __volatile (lock "addq %q1, %0" \
+ : "=m" (*mem) \
+ : "ir" ((long) (value)), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ } while (0)
#define atomic_add(mem, value) \
- (void) ({ if (__builtin_constant_p (value) && (value) == 1) \
- atomic_increment (mem); \
- else if (__builtin_constant_p (value) && (value) == 1) \
- atomic_decrement (mem); \
- else if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "addb %b1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "addw %w1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "addl %1, %0" \
- : "=m" (*mem) \
- : "ir" (value), "m" (*mem)); \
- else \
- __asm __volatile (LOCK_PREFIX "addq %q1, %0" \
- : "=m" (*mem) \
- : "ir" ((long) (value)), "m" (*mem)); \
- })
+ __arch_add_body (LOCK_PREFIX, atomic, mem, value)
+
+#define __arch_add_cprefix \
+ "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_add(mem, value) \
+ __arch_add_body (__arch_add_cprefix, catomic, mem, value)
#define atomic_add_negative(mem, value) \
@@ -194,24 +268,37 @@ typedef uintmax_t uatomic_max_t;
__result; })
-#define atomic_increment(mem) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "incb %b0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "incw %w0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "incl %0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else \
- __asm __volatile (LOCK_PREFIX "incq %q0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- })
+#define __arch_increment_body(lock, mem) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "incb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "incw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "incl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ __asm __volatile (lock "incq %q0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ } while (0)
+
+#define atomic_increment(mem) __arch_increment_body (LOCK_PREFIX, mem)
+
+#define __arch_increment_cprefix \
+ "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_increment(mem) \
+ __arch_increment_body (__arch_increment_cprefix, mem)
#define atomic_increment_and_test(mem) \
@@ -235,24 +322,37 @@ typedef uintmax_t uatomic_max_t;
__result; })
-#define atomic_decrement(mem) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "decb %b0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "decw %w0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "decl %0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- else \
- __asm __volatile (LOCK_PREFIX "decq %q0" \
- : "=m" (*mem) \
- : "m" (*mem)); \
- })
+#define __arch_decrement_body(lock, mem) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "decb %b0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "decw %w0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "decl %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ __asm __volatile (lock "decq %q0" \
+ : "=m" (*mem) \
+ : "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ } while (0)
+
+#define atomic_decrement(mem) __arch_decrement_body (LOCK_PREFIX, mem)
+
+#define __arch_decrement_cprefix \
+ "cmpl $0, %%fs:%P2\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_decrement(mem) \
+ __arch_decrement_body (__arch_decrement_cprefix, mem)
#define atomic_decrement_and_test(mem) \
@@ -277,27 +377,28 @@ typedef uintmax_t uatomic_max_t;
#define atomic_bit_set(mem, bit) \
- (void) ({ if (sizeof (*mem) == 1) \
- __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1L << (bit))); \
- else if (sizeof (*mem) == 2) \
- __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1L << (bit))); \
- else if (sizeof (*mem) == 4) \
- __asm __volatile (LOCK_PREFIX "orl %2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "ir" (1L << (bit))); \
- else if (__builtin_constant_p (bit) && (bit) < 32) \
- __asm __volatile (LOCK_PREFIX "orq %2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "i" (1L << (bit))); \
- else \
- __asm __volatile (LOCK_PREFIX "orq %q2, %0" \
- : "=m" (*mem) \
- : "m" (*mem), "r" (1UL << (bit))); \
- })
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "orb %b2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "orw %w2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "orl %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "ir" (1L << (bit))); \
+ else if (__builtin_constant_p (bit) && (bit) < 32) \
+ __asm __volatile (LOCK_PREFIX "orq %2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "i" (1L << (bit))); \
+ else \
+ __asm __volatile (LOCK_PREFIX "orq %q2, %0" \
+ : "=m" (*mem) \
+ : "m" (*mem), "r" (1UL << (bit))); \
+ } while (0)
#define atomic_bit_test_set(mem, bit) \
@@ -322,3 +423,56 @@ typedef uintmax_t uatomic_max_t;
#define atomic_delay() asm ("rep; nop")
+
+
+#define atomic_and(mem, mask) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (LOCK_PREFIX "andb %1, %b0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (LOCK_PREFIX "andw %1, %w0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (LOCK_PREFIX "andl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ else \
+ __asm __volatile (LOCK_PREFIX "andq %1, %q0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem)); \
+ } while (0)
+
+
+#define __arch_or_body(lock, mem, mask) \
+ do { \
+ if (sizeof (*mem) == 1) \
+ __asm __volatile (lock "orb %1, %b0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 2) \
+ __asm __volatile (lock "orw %1, %w0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else if (sizeof (*mem) == 4) \
+ __asm __volatile (lock "orl %1, %0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ else \
+ __asm __volatile (lock "orq %1, %q0" \
+ : "=m" (*mem) \
+ : "ir" (mask), "m" (*mem), \
+ "i" (offsetof (tcbhead_t, multiple_threads))); \
+ } while (0)
+
+#define atomic_or(mem, mask) __arch_or_body (LOCK_PREFIX, mem, mask)
+
+#define __arch_or_cprefix \
+ "cmpl $0, %%fs:%P3\n\tje 0f\n\tlock\n0:\t"
+
+#define catomic_or(mem, mask) __arch_or_body (__arch_or_cprefix, mem, mask)