From: Gabor M. <me...@us...> - 2009-02-16 22:13:16
|
Update of /cvsroot/sbcl/sbcl/src/compiler/generic In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv11635/src/compiler/generic Modified Files: objdef.lisp Log Message: 1.0.25.29: thread state visibility and synchronization C does not guarantee that changes made to a volatile variable in one thread are visibile to other threads. Use locking primitives (that have memory barrier semantics) for that purpose. Thus, all_threads need not be volatile: it's always accessed while holding all_threads_lock. Thread state does not need volatile either, as signal a handlers don't change it (save for sig_stop_for_gc_handler but that sets it restores its value). But visibility issues can arise and potentially deadlock in stop_the_world, so the thread state is given a lock. And to reduce busy looping while waiting for the state to change to STATE_SUSPENDED a condition variable is added as well. Also convert sig_stop_for_gc_handler to use wait_for_thread_state_change which frees up SIG_RESUME_FROM_GC. I think this also guarantees that the changes made by the gc are visible in other threads on non x86 platforms (on x86 it's already the case). With these changes threads.impure.lisp runs 10% a faster in real time. Index: objdef.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/generic/objdef.lisp,v retrieving revision 1.59 retrieving revision 1.60 diff -u -d -r1.59 -r1.60 --- objdef.lisp 11 Feb 2009 12:46:19 -0000 1.59 +++ objdef.lisp 16 Feb 2009 21:44:11 -0000 1.60 @@ -374,14 +374,18 @@ ;; tls[0] = NO_TLS_VALUE_MARKER_WIDETAG because a the tls index slot ;; of a symbol is initialized to zero (no-tls-value-marker) - (os-thread :c-type "volatile os_thread_t") + (os-thread :c-type "os_thread_t") ;; This is the original address at which the memory was allocated, ;; which may have different alignment then what we prefer to use. - ;; Kept here so that when the thread dies we can releast the whole + ;; Kept here so that when the thread dies we can release the whole ;; memory we reserved. (os-address :c-type "void *" :length #!+alpha 2 #!-alpha 1) #!+sb-thread (os-attr :c-type "pthread_attr_t *" :length #!+alpha 2 #!-alpha 1) + #!+sb-thread + (state-lock :c-type "pthread_mutex_t *" :length #!+alpha 2 #!-alpha 1) + #!+sb-thread + (state-cond :c-type "pthread_cond_t *" :length #!+alpha 2 #!-alpha 1) (binding-stack-start :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1) (binding-stack-pointer :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1) (control-stack-start :c-type "lispobj *" :length #!+alpha 2 #!-alpha 1) @@ -393,7 +397,7 @@ (prev :c-type "struct thread *" :length #!+alpha 2 #!-alpha 1) (next :c-type "struct thread *" :length #!+alpha 2 #!-alpha 1) ;; starting, running, suspended, dead - (state :c-type "volatile lispobj") + (state :c-type "lispobj") (tls-cookie) ; on x86, the LDT index #!+(or x86 x86-64) (pseudo-atomic-bits) (interrupt-data :c-type "struct interrupt_data *" |