This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Thread-, Signal- and Cancellation-safety documentation


On May 30, 2013, Torvald Riegel <triegel@redhat.com> wrote:

> Also, it says that one function should virtually "happen after another",
> which at least suggests a total order.

Which may well have been enough of a reason to drop that broken
definition in favor of the current one.

> What I primarily want to see
> is a proper definition of thread safety,

Given that posix rules data races as undefined (as cited in the last of
the messages I posted yesterday, a passage I wish I'd noted long ago,
for it would have saved us all a lot of speculation in this conversation)
and it specifies the behavior of various functions, requiring them to be
thread safe even if they are required to manipulate internal data
structures that, in the absence of synchronization, would involve data
races, it must follow that, when posix writes âsafe to callâ, one of the
requirements must be that the implementations must ensure such data
races are avoided while offering the specified functionality.

Can you derive any additional requirement from the standard?

Should there be any additional requirement?

>> Say, it might be the case that observe-A-if-you-observed-B (transitive
>> observability?)

> Note that we can have two things here, informally:
> 1) observe A if you observed B
> 2) observe A if you observed B and B observed A

> Roughly, 1) is -- or is meant to mean :) -- sequential consistency, and
> 2) is more what you'd get from a normal acquire release.  Both can make
> sense; 2) can give you the same effect but you need to know (or it needs
> to be reasonable to know) whether B observed A.

Given that memory-synchronizing operations are defined as synchronizing
with the global, shared memory, I understand it follows that such
synchronizing operations are events that define a total order among
themselves.  Therefore, it must follow that an event F that
happened-before synchronization event G (F and G in the same thread)
must be observable by event Q that happened-after synchronization event
P (P and Q in the same thread) if G happened-before P (per the total
ordering of synchronization operations).  The total ordering of
synchronization events makes the distinction irrelevant: it doesn't
matter if someone in the middle observed something, there's a direct
happens-before relationship between the synchronization operations that
ensure observability across the synchronization events and, if there are
no such synchronization events, then there's a data race that makes it
undefined, i.e., the observability is possible but not certain.

> Yes.  Even further indication that "thread-safe" can be mean different
> things to different people :)

There's no dispute about that.  The dispute is on whether these
different interpretations are derived from the standard, or from
assumptions that don't find support in it.

> The stronger guarantees aren't something that you can necessarily
> enforce externally: You typically can if it's just about lacking memory
> barriers, but if the implementation is caching internally (eg, in
> thread-local vars), you can't enforce an update without the
> implementation making this possible (by not caching).

Caching in thread-local vars would apparently permitted only as long as
the synchronization primitives defined in the standard synchronized them
with global memory too.

I'm even getting the idea that the standard is defined such that it
would be valid to buffer all memory writes (not just those inside the
library implementation) in an infinite thread-local cache, that would be
flushed and cleared upon user-initiated synchronization operations.  In
distributed systems speak, it's as if each process (thread) made changes
to memory only locally, and communicated with the global memory to flush
local changes and pull updates at the synchronization primitives.  It
doesn't, however, rule out asynchronous messages from being send or
received, which is why additional care needs to be taken to avoid races.

> 1) Do you respect established inter-thread happens-before?

Who, me? :-D

I believe the standard requires the model I described above, in which
the synchronization primitives defined in the standard define a total
happens-before order.

I'm not convinced, however, that this respect has anything to do with
thread safety.  It's different levels of abstraction we're talking
about.  A âsafe to callâ requirement should mean it's safe to call
regardless of the underlying memory model; the implementation should
ensure it behaves as mandated by the specification as long as all
threads behave within the defined constraints (i.e., not exercising
undefined behavior or calling unsafe functions).

> 2) Do you establish additional inter-thread happens-before relations
> that make sense for the abstract functionality that the particular
> function offers?

Only where the standard specifies that such a relation is established.

> Do you preserve transitivity of happens-before (I mean
> C/C++ acquire/release vs. acquire/consume, for example)?

I believe the total order established by synchronization primitives does
that.  I don't see that the standard requires any other specified
primitive to do so.

> For example, imagine that what a thread-safe function produces, at the
> abstract level, is like what a counter would produce.  Do you think it
> makes sense to not give it any implied inter-thread happens-before?

I'm afraid I don't understand the question.  What does a counter
produce, is it a frequency, a period, the value it holds when you look
at it?

As in, do you mean something like { static int i; return i++; }?  A
global clock that advances regardless of calls, so that the function
returns its current value?  Something else?  Anyway, for both cases I
mentioned, my answer would be âit might make sense or it might not,
depending on its purposeâ

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]