3 #ifdef LISP_FEATURE_SB_THREAD
4 #include <architecture/i386/table.h>
5 #include <i386/user_ldt.h>
6 #include <mach/mach_init.h>
10 #include "x86-darwin-os.h"
12 #ifdef LISP_FEATURE_SB_THREAD
14 pthread_mutex_t modify_ldt_lock = PTHREAD_MUTEX_INITIALIZER;
16 void set_data_desc_size(data_desc_t* desc, unsigned long size)
18 desc->limit00 = (size - 1) & 0xffff;
19 desc->limit16 = ((size - 1) >> 16) &0xf;
22 void set_data_desc_addr(data_desc_t* desc, void* addr)
24 desc->base00 = (unsigned int)addr & 0xffff;
25 desc->base16 = ((unsigned int)addr & 0xff0000) >> 16;
26 desc->base24 = ((unsigned int)addr & 0xff000000) >> 24;
31 int arch_os_thread_init(struct thread *thread) {
32 #ifdef LISP_FEATURE_SB_THREAD
36 data_desc_t ldt_entry = { 0, 0, 0, DESC_DATA_WRITE,
37 3, 1, 0, DESC_DATA_32B, DESC_GRAN_BYTE, 0 };
39 set_data_desc_addr(&ldt_entry, (unsigned long) thread);
40 set_data_desc_size(&ldt_entry, dynamic_values_bytes);
42 thread_mutex_lock(&modify_ldt_lock);
43 n = i386_set_ldt(LDT_AUTO_ALLOC, (union ldt_entry*) &ldt_entry, 1);
46 perror("i386_set_ldt");
47 lose("unexpected i386_set_ldt(..) failure\n");
49 thread_mutex_unlock(&modify_ldt_lock);
51 FSHOW_SIGNAL((stderr, "/ TLS: Allocated LDT %x\n", n));
56 __asm__ __volatile__ ("mov %0, %%fs" : : "r"(sel));
59 pthread_setspecific(specials,thread);
62 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
65 /* Signal handlers are run on the control stack, so if it is exhausted
66 * we had better use an alternate stack for whatever signal tells us
67 * we've exhausted it */
68 sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
70 sigstack.ss_size = 32*SIGSTKSZ;
71 sigaltstack(&sigstack,0);
73 return 1; /* success */
76 int arch_os_thread_cleanup(struct thread *thread) {
77 #if defined(LISP_FEATURE_SB_THREAD)
78 int n = thread->tls_cookie;
80 /* Set the %%fs register back to 0 and free the the ldt
81 * by setting it to NULL.
83 FSHOW_SIGNAL((stderr, "/ TLS: Freeing LDT %x\n", n));
85 __asm__ __volatile__ ("mov %0, %%fs" : : "r"(0));
86 thread_mutex_lock(&modify_ldt_lock);
87 i386_set_ldt(n, NULL, 1);
88 thread_mutex_unlock(&modify_ldt_lock);
90 return 1; /* success */