All Manuals > LispWorks User Guide and Reference Manual > 15 Multiprocessing > 15.10 Low level atomic operations > 15.10.2 Ensuring order of memory between operations in different threads

NextPrevUpTopContentsIndex

15.10.2.1 Example of ensuring order of memory

Suppose you have two code fragments, which may end up executed in parallel, and both of which access a global structure *gs* . The first fragment is a setter, and you can be sure that it is not executed in parallel to itself (normally because it actually runs inside a lock):

(setf
  (my-structure-value-slot *gs*)   ; store1
  some-value)
(setf
  (my-structure-counter-slot *gs*) ; store2
  counter)

The second fragment is the reader. You want to guarantee that it gets a value that was stored after the counter reached some value (the counter value always increases). You may think that this will suffice:

(if (>=
     (my-structure-counter-slot *gs*) ; load1
     counter)
    (my-structure-value-slot *gs*)    ; load2
  (.. something else ...))

Programmatically, if the >= is true then store2 already occurred before load1 , therefore store1 also occurred before load1 , and load2 which happens after load1 must happen after store1 .

On a single CPU that is true. On a computer with multiple CPU cores it can go wrong (that is, load2 can happen before store1 ) because of two possible reasons:

  1. load2 may happen before load1 .
  2. store2 may happen before store1 .

To guarantee that load2 happens after store1 , both of these possibilities need to be dealt with. Thus the setter has to be:

(setf (my-structure-value-slot *gs*)   ; store1
      some-value)
(sys:ensure-stores-after-stores)       ; ensure store order
(setf (my-structure-counter-slot *gs*) ; store2
      (incf-counter))

and the reader has to be:

(if (> (my-structure-counter-slot *gs*) ; load1
       my-counter)
    (progn
      (sys:ensure-loads-after-loads)    ; ensure load order
      (my-structure-value-slot *gs*))   ; load2
  (.. something else ...))

Note that somehow both threads know about counter , and normally will have to synchronize the getting of its value too.


LispWorks User Guide and Reference Manual - 21 Dec 2011

NextPrevUpTopContentsIndex