summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2003-05-21 08:21:24 +0000
committermtm <mtm@FreeBSD.org>2003-05-21 08:21:24 +0000
commite91b0202f951121758a11b8c9cf462a8fd054219 (patch)
tree8e169223b833630472246db00958df59c3b3d30a /lib/libthr
parentab966f1217f865494769987074763f2f25194cbd (diff)
downloadFreeBSD-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.c32
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));
OpenPOWER on IntegriCloud