+int arch_os_thread_init(struct thread *thread) {
+ stack_t sigstack;
+#ifdef LISP_FEATURE_SB_THREAD
+ struct user_desc ldt_entry = {
+ 1, 0, 0, /* index, address, length filled in later */
+ 1, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 1
+ };
+ int n;
+ thread_mutex_lock(&modify_ldt_lock);
+ n=modify_ldt(0,local_ldt_copy,sizeof local_ldt_copy);
+ /* get next free ldt entry */
+
+ if(n) {
+ u32 *p;
+ for(n=0,p=local_ldt_copy;*p;p+=LDT_ENTRY_SIZE/sizeof(u32))
+ n++;
+ }
+ ldt_entry.entry_number=n;
+ ldt_entry.base_addr=(unsigned long) thread;
+ ldt_entry.limit=dynamic_values_bytes;
+ ldt_entry.limit_in_pages=0;
+ if (modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0) {
+ thread_mutex_unlock(&modify_ldt_lock);
+ /* modify_ldt call failed: something magical is not happening */
+ return 0;
+ }
+ __asm__ __volatile__ ("movw %w0, %%fs" : : "q"
+ ((n << 3) /* selector number */
+ + (1 << 2) /* TI set = LDT */
+ + 3)); /* privilege level */
+ thread->tls_cookie=n;
+ pthread_mutex_unlock(&modify_ldt_lock);
+
+ if(n<0) return 0;
+ pthread_setspecific(specials,thread);
+#endif
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+ /* Signal handlers are run on the control stack, so if it is exhausted
+ * we had better use an alternate stack for whatever signal tells us
+ * we've exhausted it */
+ sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
+ sigstack.ss_flags=0;
+ sigstack.ss_size = 32*SIGSTKSZ;
+ if(sigaltstack(&sigstack,0)<0)
+ lose("Cannot sigaltstack: %s\n",strerror(errno));
+#endif
+ return 1;
+}
+
+struct thread *debug_get_fs() {
+ register u32 fs;
+ __asm__ __volatile__ ("movl %%fs,%0" : "=r" (fs) : );
+ return (struct thread *)fs;
+}
+
+/* free any arch/os-specific resources used by thread, which is now
+ * defunct. Not called on live threads
+ */
+
+int arch_os_thread_cleanup(struct thread *thread) {
+ struct user_desc ldt_entry = {
+ 0, 0, 0,
+ 0, MODIFY_LDT_CONTENTS_DATA, 0, 0, 0, 0
+ };
+ int result;
+
+ ldt_entry.entry_number=thread->tls_cookie;
+ thread_mutex_lock(&modify_ldt_lock);
+ result = modify_ldt(1, &ldt_entry, sizeof (ldt_entry));
+ thread_mutex_unlock(&modify_ldt_lock);
+ return result;
+}
+
+
+