summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-06-01 21:42:31 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-06-01 21:42:31 +0200
commit04ac1241a4cd004872282c2c82ec37fa33925292 (patch)
tree0d87b349348dd9f8a7e0714dc98a0eb0759beba6
parent35220b39bcb72030d6121350e91ca033b82e47ce (diff)
parent0bbb676a2342367c4e52b35e890f24667dabb348 (diff)
Merge branch 't/tls' into refs/top-bases/t/tls-threadvar
-rw-r--r--.topmsg16
-rw-r--r--include/errno.h13
-rw-r--r--mach/setup-thread.c10
-rw-r--r--sysdeps/mach/hurd/i386/init-first.c11
-rw-r--r--sysdeps/mach/hurd/i386/tls.h21
-rw-r--r--sysdeps/mach/hurd/profil.c2
-rw-r--r--sysdeps/mach/hurd/setitimer.c2
-rw-r--r--sysdeps/mach/thread_state.h2
8 files changed, 47 insertions, 30 deletions
diff --git a/.topmsg b/.topmsg
index 6f7e3b13b6..38bf5ea403 100644
--- a/.topmsg
+++ b/.topmsg
@@ -1,10 +1,14 @@
-From: Thomas Schwinge <thomas@schwinge.name>
-Subject: [PATCH] tls
+COMMITED
-TLS support.
+From: Samuel Thibault <samuel.thibault@gnu.org>
+Subject: [PATCH] hurd: add TLS support
2009-07-30 Samuel Thibault <samuel.thibault@gnu.org>
+ Add TLS support: __mach_setup_tls allocates and sets
+ architecture state for the TLS area. i386 fork needs to
+ propagate the segment kernel definitions.
+
* sysdeps/mach/hurd/bits/libc-lock.h [_LIBC - 0]: Include <tls.h>
* sysdeps/mach/hurd/tls.h: Include <stdint.h> and <sysdep.h>
* include/errno.h (__GNU__): Do not define TLS errno for now.
@@ -21,8 +25,10 @@ TLS support.
* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler): Use
i386_REGS_SEGS_STATE instead of i386_THREAD_STATE.
- * sysdeps/mach/hurd/i386/tls.h (_hurd_tls_init): Use kern_return_t
- error type. Use first GDT slot, 0x48.
+ * sysdeps/mach/hurd/i386/tls.h (__i386_selector_is_ldt): New
+ macro.
+ (_hurd_tls_init): Use kern_return_t error type. Use
+ __i386_selector_is_ldt to test for LDT segment type.
(_hurd_tls_fork): Use kern_return_t error type. Duplicate existing LDT
descriptor instead of creating a new one.
(_hurd_tls_new): New function, creates a new descriptor and updates tcb.
diff --git a/include/errno.h b/include/errno.h
index 669e4789f3..4f983889ae 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -26,12 +26,13 @@ extern int rtld_errno attribute_hidden;
# include <tls.h>
-# undef errno
-# if IS_IN (libc)
-# define errno __libc_errno
-# else
-# define errno errno /* For #ifndef errno tests. */
-# endif
+# if !defined __GNU__
+# undef errno
+# if IS_IN (libc)
+# define errno __libc_errno
+# else
+# define errno errno /* For #ifndef errno tests. */
+# endif
extern __thread int errno attribute_tls_model_ie;
# endif
diff --git a/mach/setup-thread.c b/mach/setup-thread.c
index 1505027feb..c1de3a1fb6 100644
--- a/mach/setup-thread.c
+++ b/mach/setup-thread.c
@@ -88,16 +88,16 @@ __mach_setup_tls (thread_t thread)
mach_msg_type_number_t tssize = MACHINE_THREAD_STATE_COUNT;
tcbhead_t *tcb;
+ tcb = _dl_allocate_tls (NULL);
+ if (tcb == NULL)
+ return KERN_RESOURCE_SHORTAGE;
+
if (error = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
(natural_t *) &ts, &tssize))
return error;
assert (tssize == MACHINE_THREAD_STATE_COUNT);
- tcb = _dl_allocate_tls(NULL);
- if (!tcb)
- return KERN_RESOURCE_SHORTAGE;
-
- _hurd_tls_new(thread, &ts, tcb);
+ _hurd_tls_new (thread, &ts, tcb);
error = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
(natural_t *) &ts, tssize);
diff --git a/sysdeps/mach/hurd/i386/init-first.c b/sysdeps/mach/hurd/i386/init-first.c
index 643d7dbdae..7895206417 100644
--- a/sysdeps/mach/hurd/i386/init-first.c
+++ b/sysdeps/mach/hurd/i386/init-first.c
@@ -117,9 +117,7 @@ init1 (int argc, char *arg0, ...)
then after the environment pointers there is no Hurd
data block; the argument strings start there. */
if ((void *) d == argv[0])
- {
- return;
- }
+ return;
#ifndef SHARED
__libc_enable_secure = d->flags & EXEC_SECURE;
@@ -206,9 +204,10 @@ init (int *data)
assert (d->phdrsz % sizeof (ElfW(Phdr)) == 0);
}
- /* We need to setup TLS before starting sigthread */
- extern void __pthread_initialize_minimal(void);
- __pthread_initialize_minimal();
+ /* We need to setup TLS before starting the signal thread. */
+ extern void __pthread_initialize_minimal (void);
+ if (__pthread_initialize_minimal != NULL)
+ __pthread_initialize_minimal ();
#endif
/* The user might have defined a value for this, to get more variables.
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index e94db7a925..fe0622868b 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -62,6 +62,15 @@ typedef struct
#define TLS_TCB_AT_TP 1
#define TLS_DTV_AT_TP 0
+/* Alignment requirement for TCB.
+
+ Some processors such as Intel Atom pay a big penalty on every
+ access using a segment override if that segment's base is not
+ aligned to the size of a cache line. (See Intel 64 and IA-32
+ Architectures Optimization Reference Manual, section 13.3.3.3,
+ "Segment Base".) On such machines, a cache line is 64 bytes. */
+#define TCB_ALIGNMENT 64
+
#ifndef __ASSEMBLER__
/* Use i386-specific RPCs to arrange that %gs segment register prefix
@@ -72,6 +81,8 @@ typedef struct
# define __i386_set_gdt(thr, sel, desc) ((void) (thr), (void) (sel), (void) (desc), MIG_BAD_ID)
# endif
+#define __i386_selector_is_ldt(sel) (!!((sel) & 4))
+
# include <errno.h>
# include <assert.h>
@@ -162,10 +173,10 @@ _hurd_tls_fork (thread_t child, thread_t orig, struct i386_thread_state *state)
return 0;
struct descriptor desc, *_desc = &desc;
- kern_return_t err;
+ error_t err;
unsigned int count = 1;
- if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
+ if (__glibc_unlikely (__i386_selector_is_ldt(sel)))
err = __i386_get_ldt (orig, sel, 1, &_desc, &count);
else
err = __i386_get_gdt (orig, sel, &desc);
@@ -174,7 +185,7 @@ _hurd_tls_fork (thread_t child, thread_t orig, struct i386_thread_state *state)
if (err)
return err;
- if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
+ if (__glibc_unlikely (__i386_selector_is_ldt(sel)))
err = __i386_set_ldt (child, sel, &desc, 1);
else
err = __i386_set_gdt (child, &sel, desc);
@@ -193,12 +204,12 @@ _hurd_tls_new (thread_t child, struct i386_thread_state *state, tcbhead_t *tcb)
return 0;
HURD_TLS_DESC_DECL (desc, tcb);
- kern_return_t err;
+ error_t err;
tcb->tcb = tcb;
tcb->self = child;
- if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */
+ if (__glibc_unlikely (__i386_selector_is_ldt(sel)))
err = __i386_set_ldt (child, sel, &desc, 1);
else
err = __i386_set_gdt (child, &sel, desc);
diff --git a/sysdeps/mach/hurd/profil.c b/sysdeps/mach/hurd/profil.c
index 27145ea32a..17028522a7 100644
--- a/sysdeps/mach/hurd/profil.c
+++ b/sysdeps/mach/hurd/profil.c
@@ -69,7 +69,7 @@ update_waiter (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
err = __mach_setup_thread (__mach_task_self (), profile_thread,
&profile_waiter, NULL, NULL);
if (! err)
- err = __mach_setup_tls(profile_thread);
+ err = __mach_setup_tls (profile_thread);
}
else
err = 0;
diff --git a/sysdeps/mach/hurd/setitimer.c b/sysdeps/mach/hurd/setitimer.c
index b3341b8d4e..48346e2eab 100644
--- a/sysdeps/mach/hurd/setitimer.c
+++ b/sysdeps/mach/hurd/setitimer.c
@@ -226,7 +226,7 @@ setitimer_locked (const struct itimerval *new, struct itimerval *old,
&timer_thread,
&_hurd_itimer_thread_stack_base,
&_hurd_itimer_thread_stack_size))
- || (err = __mach_setup_tls(_hurd_itimer_thread)))
+ || (err = __mach_setup_tls (_hurd_itimer_thread)))
{
__thread_terminate (_hurd_itimer_thread);
_hurd_itimer_thread = MACH_PORT_NULL;
diff --git a/sysdeps/mach/thread_state.h b/sysdeps/mach/thread_state.h
index 0914b84244..c382eb995a 100644
--- a/sysdeps/mach/thread_state.h
+++ b/sysdeps/mach/thread_state.h
@@ -38,7 +38,7 @@
#endif
#endif
#ifndef MACHINE_THREAD_STATE_FIX_NEW
-#define MACHINE_THREAD_STATE_FIX_NEW(ts)
+# define MACHINE_THREAD_STATE_FIX_NEW(ts)
#endif
/* These functions are of use in machine-dependent signal trampoline