diff options
author | mtm <mtm@FreeBSD.org> | 2003-05-21 08:21:24 +0000 |
---|---|---|
committer | mtm <mtm@FreeBSD.org> | 2003-05-21 08:21:24 +0000 |
commit | e91b0202f951121758a11b8c9cf462a8fd054219 (patch) | |
tree | 8e169223b833630472246db00958df59c3b3d30a /lib/libthr | |
parent | ab966f1217f865494769987074763f2f25194cbd (diff) | |
download | FreeBSD-src-e91b0202f951121758a11b8c9cf462a8fd054219.zip FreeBSD-src-e91b0202f951121758a11b8c9cf462a8fd054219.tar.gz |
o Make the defenition of _set_curthread() match its declaration
in thr_private.h
o Lock down the ldt_entries array and ldt_free, which points to
the next free slot. As noted in the comments, it's necessary
to special case the initial_thread because %gs is not setup
for it yet. This is ok because that early in the program there
won't be any reentrancy issues anyways.
Approved by: re/blanket libthr
Diffstat (limited to 'lib/libthr')
-rw-r--r-- | lib/libthr/arch/i386/i386/_setcurthread.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/lib/libthr/arch/i386/i386/_setcurthread.c b/lib/libthr/arch/i386/i386/_setcurthread.c index 94c6561..b561f3f 100644 --- a/lib/libthr/arch/i386/i386/_setcurthread.c +++ b/lib/libthr/arch/i386/i386/_setcurthread.c @@ -29,21 +29,29 @@ #include <sys/types.h> #include <sys/ucontext.h> +#include <pthread.h> #include <stdio.h> #include <machine/sysarch.h> #include <machine/segments.h> +#include "thr_private.h" + #define MAXTHR 128 #define LDT_INDEX(x) (((long)(x) - (long)ldt_entries) / sizeof(ldt_entries[0])) -void **ldt_free = NULL; -static int ldt_inited = 0; -void *ldt_entries[MAXTHR]; +void **ldt_free = NULL; +void *ldt_entries[MAXTHR]; +static int ldt_inited = 0; +static spinlock_t ldt_lock = _SPINLOCK_INITIALIZER; static void ldt_init(void); +/* + * Initialize the array of ldt_entries and the next free slot. + * This routine must be called with the global ldt lock held. + */ static void ldt_init(void) { @@ -62,21 +70,32 @@ ldt_init(void) void _retire_thread(void *entry) { + _SPINLOCK(&ldt_lock); if (ldt_free == NULL) *(void **)entry = NULL; else *(void **)entry = *ldt_free; ldt_free = entry; + _SPINUNLOCK(&ldt_lock); } void * -_set_curthread(ucontext_t *uc, void *thr) +_set_curthread(ucontext_t *uc, struct pthread *thr) { union descriptor desc; void **ldt_entry; int ldt_index; int error; + /* + * If we are setting up the initial thread, the gs register + * won't be setup for the current thread. In any case, we + * don't need protection from re-entrancy at this point in + * the life of the program. + */ + if (thr != _thread_initial) + _SPINLOCK(&ldt_lock); + if (ldt_inited == NULL) ldt_init(); @@ -89,11 +108,14 @@ _set_curthread(ucontext_t *uc, void *thr) ldt_entry = ldt_free; ldt_free = (void **)*ldt_entry; + if (thr != _thread_initial) + _SPINUNLOCK(&ldt_lock); + /* * Cache the address of the thread structure here. This is * what the gs register will point to. */ - *ldt_entry = thr; + *ldt_entry = (void *)thr; ldt_index = LDT_INDEX(ldt_entry); bzero(&desc, sizeof(desc)); |