X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fcell.lisp;h=9596bc9fee4f6f2f1d27b5a3df53ea04b2c8581e;hb=4d5a8689d1d303f65c2fa933bb8757063641a8f9;hp=6a3a89c5af440209e1461a018022c0c4a0f07661;hpb=862c0325616a991a5bd7b50d79f7176d2115493b;p=sbcl.git diff --git a/src/compiler/x86-64/cell.lisp b/src/compiler/x86-64/cell.lisp index 6a3a89c..9596bc9 100644 --- a/src/compiler/x86-64/cell.lisp +++ b/src/compiler/x86-64/cell.lisp @@ -283,22 +283,40 @@ (define-vop (bind) (:args (val :scs (any-reg descriptor-reg)) (symbol :scs (descriptor-reg))) + (:temporary (:sc descriptor-reg :offset rax-offset) rax) (:temporary (:sc unsigned-reg) tls-index temp bsp) - (:generator 5 - (let ((tls-index-valid (gen-label))) - (load-tl-symbol-value bsp *binding-stack-pointer*) + (:generator 10 + (let ((tls-index-valid (gen-label)) + (get-tls-index-lock (gen-label)) + (release-tls-index-lock (gen-label))) + (load-binding-stack-pointer bsp) (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag) (inst add bsp (* binding-size n-word-bytes)) - (store-tl-symbol-value bsp *binding-stack-pointer* temp) - + (store-binding-stack-pointer bsp) (inst or tls-index tls-index) (inst jmp :ne tls-index-valid) - ;; allocate a new tls-index - (load-symbol-value tls-index *free-tls-index*) - (inst add tls-index 8) ;XXX surely we can do this more - (store-symbol-value tls-index *free-tls-index*) ;succintly - (inst sub tls-index 8) - (storew tls-index symbol symbol-tls-index-slot other-pointer-lowtag) + + (pseudo-atomic + (emit-label get-tls-index-lock) + (inst mov temp 1) + (inst xor rax rax) + (inst lock) + (inst cmpxchg (make-ea-for-symbol-value *tls-index-lock*) temp) + (inst jmp :ne get-tls-index-lock) + ;; now with the lock held, see if the symbol's tls index has + ;; been set in the meantime + (loadw tls-index symbol symbol-tls-index-slot other-pointer-lowtag) + (inst or tls-index tls-index) + (inst jmp :ne release-tls-index-lock) + ;; allocate a new tls-index + (load-symbol-value tls-index *free-tls-index*) + (inst add tls-index 8) ;XXX surely we can do this more + (store-symbol-value tls-index *free-tls-index*) ;succintly + (inst sub tls-index 8) + (storew tls-index symbol symbol-tls-index-slot other-pointer-lowtag) + (emit-label release-tls-index-lock) + (store-symbol-value 0 *tls-index-lock*)) + (emit-label tls-index-valid) (inst mov temp (make-ea :qword :base thread-base-tn :scale 1 :index tls-index)) @@ -327,7 +345,7 @@ ;; four temporaries? (:temporary (:sc unsigned-reg) symbol value bsp tls-index) (:generator 0 - (load-tl-symbol-value bsp *binding-stack-pointer*) + (load-binding-stack-pointer bsp) (loadw symbol bsp (- binding-symbol-slot binding-size)) (loadw value bsp (- binding-value-slot binding-size)) @@ -337,8 +355,7 @@ (storew 0 bsp (- binding-symbol-slot binding-size)) (inst sub bsp (* binding-size n-word-bytes)) - ;; we're done with value, so we can use it as a temp here - (store-tl-symbol-value bsp *binding-stack-pointer* value))) + (store-binding-stack-pointer bsp))) #!-sb-thread (define-vop (unbind) @@ -357,7 +374,7 @@ (:args (where :scs (descriptor-reg any-reg))) (:temporary (:sc unsigned-reg) symbol value bsp #!+sb-thread tls-index) (:generator 0 - (load-tl-symbol-value bsp *binding-stack-pointer*) + (load-binding-stack-pointer bsp) (inst cmp where bsp) (inst jmp :e DONE) @@ -379,8 +396,7 @@ (inst sub bsp (* binding-size n-word-bytes)) (inst cmp where bsp) (inst jmp :ne LOOP) - ;; we're done with value, so can use it as a temporary - (store-tl-symbol-value bsp *binding-stack-pointer* value) + (store-binding-stack-pointer bsp) DONE))