aboutsummaryrefslogtreecommitdiff
path: root/nptl/sysdeps/i386
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/i386')
-rw-r--r--nptl/sysdeps/i386/tls.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 7fe2222..4f2e818 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -169,6 +169,14 @@ union user_desc_init
# define INIT_SYSINFO
#endif
+#ifndef LOCK
+# ifdef UP
+# define LOCK /* nothing */
+# else
+# define LOCK "lock;"
+# endif
+#endif
+
/* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */
@@ -352,6 +360,32 @@ union user_desc_init
}})
+/* Atomic compare and exchange on TLS, returning old value. */
+#define THREAD_ATOMIC_CMPXCHG_VAL(descr, member, newval, oldval) \
+ ({ __typeof (descr->member) __ret; \
+ __typeof (oldval) __old = (oldval); \
+ if (sizeof (descr->member) == 4) \
+ asm volatile (LOCK "cmpxchgl %2, %%gs:%P3" \
+ : "=a" (__ret) \
+ : "0" (__old), "r" (newval), \
+ "i" (offsetof (struct pthread, member))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); \
+ __ret; })
+
+
+/* Atomic set bit. */
+#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
+ (void) ({ if (sizeof ((descr)->member) == 4) \
+ asm volatile (LOCK "orl %1, %%gs:%P0" \
+ :: "i" (offsetof (struct pthread, member)), \
+ "ir" (1 << (bit))); \
+ else \
+ /* Not necessary for other sizes in the moment. */ \
+ abort (); })
+
+
/* Call the user-provided thread function. */
#define CALL_THREAD_FCT(descr) \
({ void *__res; \