Re: Thread-safe assignments



Pascal Costanza <pc@xxxxxxxxx> writes:

Hi,

I realize that my recent question about thread-safe caches was pretty
ambiguous. So here is a question narrowed down to something simpler,
which is hopefully more straightforward to answer.

Well, perhaps, but you've been telling us that your caches are
implemented as plists, so this is actually not the same question
simplified, but a different question.

Assume there is a global variable *var*, for example defined like this:

(cl:defvar *var* 42)

Assume there is exactly one thread forever executing the following loop:

(cl:loop
(cl:setf *var* 42)
(cl:setf *var* 84))

Furthermore, assume that other threads either don't touch *var* at
all, or only read from it.

Is it safe to assume that the reading threads will only ever read the
values 42 or 84 from *var*, or should one take into account that every
now and then, *var* may contain garbage (i.e., a bit pattern that
consists partly of the bits of 42, and partly of the bits of 84)?

I think that for most CLs, the answer is that the store into the word
is atomic. Note that I don't use the word "thread-safe" - that is a
different idea with a different answer (for it, you would have to
introduce the idea that two threads might modify the value if *var*).

To generalize, are there datatypes for which it is not safe to assume
that variable assignments are thread-safe in that sense?

Anything that must store or read/store into more than one location at
a time. More precisely, instructions themselves tend to be atomic,
but multiple instructions are not. Since storage of anything with
more than one instruction is thus non-atomic, a second processor could
in theory see a state where part of the structure is modified and part
unmodified.

What about plain references?

Same situation. If the reference is performed in an instruction, then
it will be

[Since ANSI Common Lisp doesn't say anything about multithreading,
this is by definition implementation-dependent, but nevertheless how
sufficiently safe is it to assume thread-safe variable assignments?]

In Allegro CL, there are two different kinds of references to
globally-special variables. If in the current thread the variable is
not bound at least once in a let or lambda form, then there is a
single global location that the variable is stored equivalent to
(sys:global-symbol-value '*var*). If the variable is bound, however,
e.g. as (let ((*var* nil)) (do-the-test-loop)) then there is not even
an issue of thread-safety; each value for the symbol is kept on a
per-thread basis, and is considered to be thread-local, and so it is
inherently safe.

--
Duane Rettig duane@xxxxxxxxx Franz Inc. http://www.franz.com/
555 12th St., Suite 1450 http://www.555citycenter.com/
Oakland, Ca. 94607 Phone: (510) 452-2000; Fax: (510) 452-0182
.



Relevant Pages

  • Re: Concurrency and delegates
    ... It's thread safe in that it won't throw a NullReferenceException. ... there's some behind-the-scenes locking going on? ... the memory models I've seen. ... in fact the close to the recommended practice for thread-safe ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Exploiting Dual Cores with Py_NewInterpreters separated GIL ?
    ... sufficient to make reference counting safe." ... using atomic inc/dec is as thread-safe as a non-COW String implementation ... About the term "thread-safe". ...
    (comp.lang.python)
  • Re: Concurrency and delegates
    ... Is that because there's some behind-the-scenes locking going on? ... Or is it because the event can be copied in a single CPU-atomic operation? ... it's safe - but it's not *strictly speaking* safe under ECMA. ... in fact the close to the recommended practice for thread-safe ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: setting timer
    ... >> here copied below for your convenience. ... This definition of safe has a particular meaning, ... then it is safe". ...
    (comp.unix.programmer)