From cd056980425e3fa67b8b77de3936ccb46508c3b0 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Thu, 14 Apr 2005 22:34:33 +0000 Subject: [PATCH] 0.8.21.41 Various cleanup to remove (a) code used only in the pre-futex queue system, (b) some threading code copied blindly from the x86 backend to x86-64 but is unlikely ever to actually work there --- src/code/target-unithread.lisp | 84 ++-------------------------------------- src/runtime/gencgc.c | 2 +- src/runtime/globals.c | 4 -- src/runtime/globals.h | 1 - src/runtime/interrupt.c | 22 +---------- src/runtime/thread.c | 28 +------------- src/runtime/x86-64-arch.h | 14 +++---- src/runtime/x86-64-assem.S | 5 ++- src/runtime/x86-64-linux-os.c | 77 ++---------------------------------- src/runtime/x86-64-linux-os.h | 6 +-- version.lisp-expr | 2 +- 11 files changed, 24 insertions(+), 221 deletions(-) diff --git a/src/code/target-unithread.lisp b/src/code/target-unithread.lisp index 5d2505e..e161937 100644 --- a/src/code/target-unithread.lisp +++ b/src/code/target-unithread.lisp @@ -44,67 +44,8 @@ (defstruct (mutex (:include waitqueue)) (value nil)) -#+nil -(defun wait-on-queue (queue &optional lock) - (let ((pid (current-thread-id))) - ;; FIXME what should happen if we get interrupted when we've blocked - ;; the sigcont? For that matter, can we get interrupted? - (block-sigcont) - (when lock (release-mutex lock)) - (get-spinlock queue 2 pid) - (pushnew pid (waitqueue-data queue)) - (setf (waitqueue-lock queue) 0) - (unblock-sigcont-and-sleep))) - -#+nil -(defun dequeue (queue) - (let ((pid (current-thread-id))) - (get-spinlock queue 2 pid) - (setf (waitqueue-data queue) - (delete pid (waitqueue-data queue))) - (setf (waitqueue-lock queue) 0))) - -#+nil -(defun signal-queue-head (queue) - (let ((pid (current-thread-id))) - (get-spinlock queue 2 pid) - (let ((h (car (waitqueue-data queue)))) - (setf (waitqueue-lock queue) 0) - (when h - (sb!unix:unix-kill h sb!unix:sigcont))))) - ;;;; mutex -#+nil -(defun get-mutex (lock &optional new-value (wait-p t)) - (declare (type mutex lock)) - (let ((pid (current-thread-id))) - (unless new-value (setf new-value pid)) - (assert (not (eql new-value (mutex-value lock)))) - (loop - (unless - ;; args are object slot-num old-value new-value - (sb!vm::%instance-set-conditional lock 4 nil new-value) - (dequeue lock) - (return t)) - (unless wait-p (return nil)) - (wait-on-queue lock nil)))) - -#+nil -(defun release-mutex (lock &optional (new-value nil)) - (declare (type mutex lock)) - (let ((old-value (mutex-value lock)) - (t1 nil)) - (loop - (unless - ;; args are object slot-num old-value new-value - (eql old-value - (setf t1 - (sb!vm::%instance-set-conditional lock 4 old-value new-value))) - (signal-queue-head lock) - (return t)) - (setf old-value t1)))) - (defun get-mutex (lock &optional new-value (wait-p t)) (declare (type mutex lock)) (let ((old-value (mutex-value lock))) @@ -119,27 +60,10 @@ (declare (type mutex lock)) (setf (mutex-value lock) nil)) -;;; what's the best thing to do with these on unithread? commented -;;; functions are the thread versions, just to remind me what they do -;;; there -#+nil -(defun condition-wait (queue lock) - "Atomically release LOCK and enqueue ourselves on QUEUE. Another -thread may subsequently notify us using CONDITION-NOTIFY, at which -time we reacquire LOCK and return to the caller." - (unwind-protect - (wait-on-queue queue lock) - ;; If we are interrupted while waiting, we should do these things - ;; before returning. Ideally, in the case of an unhandled signal, - ;; we should do them before entering the debugger, but this is - ;; better than nothing. - (dequeue queue) - (get-mutex lock))) - -#+nil -(defun condition-notify (queue) - "Notify one of the processes waiting on QUEUE" - (signal-queue-head queue)) + +;; FIXME need suitable stub or ERROR-signaling definitions for +;; condition-wait (queue lock) +;; condition-notify (queue) ;;;; job control diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 1dcfd35..8f9028b 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -3584,7 +3584,7 @@ garbage_collect_generation(int generation, int raise) free=fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); for(i=free-1;i>=0;i--) { os_context_t *c=th->interrupt_contexts[i]; - esp1 = (void **) *os_context_register_addr(c,reg_ESP); + esp1 = (void **) *os_context_register_addr(c,reg_SP); if(esp1>=th->control_stack_start&& esp1control_stack_end){ if(esp1=(void **)c; ptr--) { diff --git a/src/runtime/globals.c b/src/runtime/globals.c index 916cd1f..5cd53b2 100644 --- a/src/runtime/globals.c +++ b/src/runtime/globals.c @@ -42,7 +42,6 @@ lispobj *current_auto_gc_trigger; #endif #ifdef LISP_FEATURE_SB_THREAD -pid_t parent_pid; boolean stop_the_world=0; #endif @@ -64,7 +63,4 @@ void globals_init(void) /* Set foreign function call active. */ foreign_function_call_active = 1; -#ifdef LISP_FEATURE_SB_THREAD - parent_pid=getpid(); -#endif } diff --git a/src/runtime/globals.h b/src/runtime/globals.h index e8dd9de..c94cb62 100644 --- a/src/runtime/globals.h +++ b/src/runtime/globals.h @@ -35,7 +35,6 @@ extern lispobj *current_auto_gc_trigger; #endif extern lispobj *current_dynamic_space; -extern pid_t parent_pid; extern boolean stop_the_world; extern void globals_init(void); diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 65f50bf..2377308 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -124,32 +124,12 @@ struct interrupt_data * global_interrupt_data; * mask ought to be clear anyway most of the time, but may be non-zero * if we were interrupted e.g. while waiting for a queue. */ -#if 1 void reset_signal_mask () { sigset_t new; sigemptyset(&new); sigprocmask(SIG_SETMASK,&new,0); } -#else -void reset_signal_mask () -{ - sigset_t new,old; - int i; - int wrong=0; - sigemptyset(&new); - sigprocmask(SIG_SETMASK,&new,&old); - for(i=1; icode); #endif diff --git a/src/runtime/thread.c b/src/runtime/thread.c index 0f28c30..05637bb 100644 --- a/src/runtime/thread.c +++ b/src/runtime/thread.c @@ -239,7 +239,7 @@ pid_t create_thread(lispobj initial_function) { if(th==0) return 0; kid_pid=clone(new_thread_trampoline, (((void*)th->control_stack_start)+ - THREAD_CONTROL_STACK_SIZE-4), + THREAD_CONTROL_STACK_SIZE-16), CLONE_FILES|SIG_THREAD_EXIT|CLONE_VM,th); if(kid_pid>0) { @@ -256,32 +256,6 @@ pid_t create_thread(lispobj initial_function) { } #endif -/* unused */ -void destroy_thread (struct thread *th) -{ - /* precondition: the unix task has already been killed and exited. - * This is called by the parent or some other thread */ -#ifdef LISP_FEATURE_GENCGC - gc_alloc_update_page_tables(0, &th->alloc_region); -#endif - get_spinlock(&all_threads_lock,th->pid); - th->unbound_marker=0; /* for debugging */ - if(th==all_threads) - all_threads=th->next; - else { - struct thread *th1=all_threads; - while(th1 && th1->next!=th) th1=th1->next; - if(th1) th1->next=th->next; /* unlink */ - } - release_spinlock(&all_threads_lock); - if(th && th->tls_cookie>=0) arch_os_thread_cleanup(th); - os_invalidate((os_vm_address_t) th->control_stack_start, - ((sizeof (lispobj)) - * (th->control_stack_end-th->control_stack_start)) + - BINDING_STACK_SIZE+ALIEN_STACK_SIZE+dynamic_values_bytes+ - 32*SIGSTKSZ); -} - struct thread *find_thread_by_pid(pid_t pid) { struct thread *th; diff --git a/src/runtime/x86-64-arch.h b/src/runtime/x86-64-arch.h index bf3306b..4e3a18d 100644 --- a/src/runtime/x86-64-arch.h +++ b/src/runtime/x86-64-arch.h @@ -2,8 +2,8 @@ * reserved for the system libraries? If so, it would be tidy to * rename flags like _X86_ARCH_H so their names are in a part of the * namespace that we control. */ -#ifndef _X86_ARCH_H -#define _X86_ARCH_H +#ifndef _X86_64_ARCH_H +#define _X86_64_ARCH_H #define ARCH_HAS_STACK_POINTER @@ -15,15 +15,15 @@ static inline void get_spinlock(lispobj *word,long value) { -#if 0 - u32 eax=0; +#ifdef LISP_FEATURE_SB_THREAD + u64 rax=0; do { asm ("xor %0,%0\n\ lock cmpxchg %1,%2" - : "=a" (eax) + : "=a" (rax) : "r" (value), "m" (*word) : "memory", "cc"); - } while(eax!=0); + } while(rax!=0); #else *word=value; #endif @@ -35,4 +35,4 @@ release_spinlock(lispobj *word) *word=0; } -#endif /* _X86_ARCH_H */ +#endif /* _X86_64_ARCH_H */ diff --git a/src/runtime/x86-64-assem.S b/src/runtime/x86-64-assem.S index cf5b970..1751d5d 100644 --- a/src/runtime/x86-64-assem.S +++ b/src/runtime/x86-64-assem.S @@ -97,7 +97,7 @@ GNAME(call_into_lisp_first_time): mov THREAD_CONTROL_STACK_START_OFFSET(%rax) ,%rsp /* don't think too hard about what happens if we get interrupted * here */ - add $THREAD_CONTROL_STACK_SIZE-8,%rsp + add $THREAD_CONTROL_STACK_SIZE-16,%rsp jmp Lstack .text @@ -174,8 +174,9 @@ Lcall: pop %rbx /* FIXME Restore the NPX state. */ - pop %rbp # c-sp + /* return value is already in rax where lisp expects it */ + leave ret .size GNAME(call_into_lisp), . - GNAME(call_into_lisp) diff --git a/src/runtime/x86-64-linux-os.c b/src/runtime/x86-64-linux-os.c index c996813..6633b32 100644 --- a/src/runtime/x86-64-linux-os.c +++ b/src/runtime/x86-64-linux-os.c @@ -1,6 +1,6 @@ /* - * The x86 Linux incarnation of arch-dependent OS-dependent routines. - * See also "linux-os.c". + * The x86-64 Linux incarnation of arch-dependent OS-dependent + * routines. See also "linux-os.c". */ /* @@ -50,65 +50,13 @@ #include #include "thread.h" /* dynamic_values_bytes */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#define user_desc modify_ldt_ldt_s -#endif - -_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount ); - #include "validate.h" size_t os_vm_page_size; -u32 local_ldt_copy[LDT_ENTRIES*LDT_ENTRY_SIZE/sizeof(u32)]; - -/* This is never actually called, but it's great for calling from gdb when - * users have thread-related problems that maintainers can't duplicate */ - -void debug_get_ldt() -{ - int n=modify_ldt (0, local_ldt_copy, sizeof local_ldt_copy); - printf("%d bytes in ldt: print/x local_ldt_copy\n", n); -} - -lispobj modify_ldt_lock; /* protect all calls to modify_ldt */ - int arch_os_thread_init(struct thread *thread) { stack_t sigstack; #ifdef LISP_FEATURE_SB_THREAD - /* this must be called from a function that has an exclusive lock - * on all_threads - */ - 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; - get_spinlock(&modify_ldt_lock,thread); - 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) { - modify_ldt_lock=0; - /* modify_ldt call failed: something magical is not happening */ - return -1; - } - __asm__ __volatile__ ("movw %w0, %%fs" : : "q" - ((n << 3) /* selector number */ - + (1 << 2) /* TI set = LDT */ - + 3)); /* privilege level */ - thread->tls_cookie=n; - modify_ldt_lock=0; - - if(n<0) return 0; +#error Threads are not supported on x86-64 in this SBCL version #endif #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK /* Signal handlers are run on the control stack, so if it is exhausted @@ -122,30 +70,11 @@ int arch_os_thread_init(struct thread *thread) { return 1; } -struct thread *debug_get_fs() { - register u32 fs; - __asm__ __volatile__ ("movl %%fs,%0" : "=r" (fs) : ); - return 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 - }; - - ldt_entry.entry_number=thread->tls_cookie; - get_spinlock(&modify_ldt_lock,thread); - if (modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0) { - modify_ldt_lock=0; - /* modify_ldt call failed: something magical is not happening */ - return 0; - } - modify_ldt_lock=0; return 1; } diff --git a/src/runtime/x86-64-linux-os.h b/src/runtime/x86-64-linux-os.h index 90b34c0..ba96988 100644 --- a/src/runtime/x86-64-linux-os.h +++ b/src/runtime/x86-64-linux-os.h @@ -1,5 +1,5 @@ -#ifndef _X86_LINUX_OS_H -#define _X86_LINUX_OS_H +#ifndef _X86_64_LINUX_OS_H +#define _X86_64_LINUX_OS_H typedef struct ucontext os_context_t; typedef long os_context_register_t; @@ -11,4 +11,4 @@ static inline os_context_t *arch_os_get_context(void **void_context) { unsigned long os_context_fp_control(os_context_t *context); void os_restore_fp_control(os_context_t *context); -#endif /* _X86_LINUX_OS_H */ +#endif /* _X86_64_LINUX_OS_H */ diff --git a/version.lisp-expr b/version.lisp-expr index 966b235..5db653f 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.8.21.40" +"0.8.21.41" -- 1.7.10.4