Siebe de Vos
3/26/2015 10:45:00 PM
On 2015-03-26 01:22, Max Rottenkolber wrote:
> Hi c.l.l,
>
> Imagine we have a structure like this:
>
> (defstruct my-struct
> (read-only (error "Supply me!"))
> (read-write nil)
> (lock (bordeaux-threads:make-lock)))
>
> No we have functions that shall read/write the READ-WRITE slot and read
> the READ-ONLY slot in a thread-safe manner.
>
> (defun get-read-only (s)
> (my-struct-read-only s))
>
> (defun get-read-write (s)
> (bordeaux-threads:with-lock-held ((my-struct-lock s))
> (my-struct-read-write s)))
>
> (defun set-read-write (s v)
> (bordeaux-threads:with-lock-held ((my-struct-lock s))
> (setf (my-struct-read-write s) v)))
>
> If these functions are called concurrently, will GET-READ-ONLY be safe or
> will its result be undefined? What if SET-READ-WRITE would PUSH instead
> of SETF?
>
> Generally, BORDEAUX-THREADS doesn't seem to define what kind of writes
> and/or reads need to be mutually exclusive in order to have defined
> behavior. Maybe its obvious, but if this leads to any enlightenment I
> would love to contribute to the BORDEAUX-THREADS documentation.
>
> Regards,
> max
The questions about safety can be looked at in two ways. First you have
the high level thread control interface, including locks like you use
above. Those will work fine for control flow. From this point of view
your examples are completely safe.
The second level deals with dirty synchronization issues, like execution
order, cache synchronization, etc. So you could have:
- T1 creates a MY-STRUCT, passes it to T2, and T2 calls GET-READ-ONLY
before the memory is synchronized;
- T1 locks a MY-STRUCT, writes to READ-WRITE, unlocks, T2 locks and
still might see the old value.
I'm not sure you will find an SMP Common Lisp that can guarantee
structure access conforms to some kind of thread safety model (e.g.,
SBCL doesn't).
You should see BORDEAUX-THREADS as a unification of the different
implementations for the high level only. There is no attempt to provide
the 'Common Lisp memory model' and certainly it will not try to change
the way a struct accessor is implemented.
It's a nice idea to amend the CL spec with thread safety, but you would
probably end up with a lot of 'The consequences are undefined ...' (not
to mention ending up like C++).
Bye,
Siebe