On Jun 27, 2004, at 4:44 PM, Nathan Froyd wrote:
On Sun, Jun 27, 2004 at 02:36:06PM -0400, Randall Randall wrote:
On Jun 27, 2004, at 8:58 AM, Joe Marshall wrote:
This isn't thread safe. If two processes attempted to enter the queue simultaneously, one could get lost.
Because the second could run between evaluation of
[the contents of]
,queue and evaluation of APPEND? Okay. Is there an atomic way to do that append such that it is thread safe without using specialized machinery not available with serve-event?
CMUCL under x86 supports several "set place atomically" primitives that use the processor's cmpxchg instruction to provide true atomicity. (apropos "ATOMIC-") to have a peek at what's there. Since you're on PPC, this may not help that much...
My current method of dealing with the differences of CMUCL on PPC and x86 is to use serve-event on CMUCL, so that I have only one kind of difference (MP vs. non-MP). Given that I'm using serve-event, in which control must be explicitly passed, I shouldn't need any further effort to be effectively atomic on CMUCL. I would have preferred to have a single operation I could do on all CLs that would guarantee atomicity of an operation whether or not multiprocessing was involved, but I understand that it isn't covered by ANSI. The thread-safe (I think) version of ENQUEUE is:
(defmacro enqueue (queue) "Appends a unique ID to a queue." (let ((id (gensym))) `(let ((,id (gensym))) #+(and acl-compat (not allegro) (not cmu)) (ACL-COMPAT.MP:without-interrupts (setf ,queue (append ,queue (list ,id)))) #+allegro (MP:without-interrupts (setf ,queue (append ,queue (list ,id)))) #+cmu (setf ,queue (append ,queue (list ,id))) ,id)))
-- Randall Randall randall@randallsquared.com (706) 536-2674 Remote administration -- web applications -- consulting