X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=contrib%2Fsb-concurrency%2Fqueue.lisp;h=5fa70075ad6a9ba20fa712bfe75b260bc6dc74f0;hb=7254da92a1ba1bf8bc5a2e78a29d993f272d526e;hp=a902785cbdfd9f90edb65d5b8a020afae5c31080;hpb=713bb89f472457ec6654732b6b248b17b971f0ff;p=sbcl.git diff --git a/contrib/sb-concurrency/queue.lisp b/contrib/sb-concurrency/queue.lisp index a902785..5fa7007 100644 --- a/contrib/sb-concurrency/queue.lisp +++ b/contrib/sb-concurrency/queue.lisp @@ -80,11 +80,19 @@ and secondary value." (go :continue))) (when (eq head (sb-ext:compare-and-swap (queue-head queue) head first-node-prev)) - ;; This assignment is not present in the paper, but is - ;; equivalent to the free(head.ptr) call there: it unlinks - ;; the HEAD from the queue -- the code in the paper leaves - ;; the dangling pointer in place. - (setf (node-next first-node-prev) nil) + ;; These assignment is not present in the paper, but are + ;; equivalent to the free(head.ptr) call there. + ;; + ;; First we unlink the HEAD from the queue -- the code in + ;; the paper leaves the dangling pointer in place. + ;; + ;; Then we NIL out the slots in HEAD to help the GC, + ;; otherwise conservativism might lead to massive chains of + ;; nodes being retained. + (setf (node-next first-node-prev) nil + (node-prev head) nil + (node-next head) nil + (node-value head) nil) (return-from dequeue (values val t)))) ((eq tail head) (return-from dequeue (values nil nil)))