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: [MTASCsft PATCH WIP5 01/33] Multi Thread, Async Signal and Async Cancel safety documentation: intro


On Nov 27, 2013, Torvald Riegel <triegel@redhat.com> wrote:

> I know that *you* don't, but you'll also know that we don't really know
> what POSIX really intents MT-Safe to be :)

I know that you don't, but I believe I have a very clear picture in my
mind.  I've just reread all the relevant parts of POSIX, and I didn't
see any hint of a conflict with my understanding, that POSIX means
MT-Safe as funcitons that are safe to call in the presence of other
threads, i.e., that will behave as documented regardless of what other
threads are doing, as long as they all refrain from invoking undefined
behavior.

This is perfectly sufficient as a user-visible definition.  It doesn't
bring with it any inter-thread ordering requirements; those arise from
the user-visible synchronization primitives only, which no functions are
required to use internally, for the simple fact that no function is
required to perform synchronization.  That possibility is  explicitly
stated as conditional: when necessary.

The internal library implementation may need to be aware of the
underlying hardware and language memory models, and the application may
want to take advantage of additional flexibility provided by them, but
those are outside the scope of POSIX, and of the definition of whether
POSIX-defined interfaces are MT-Safe.

I refuse to repeat the discussion we've had before.  I proved that some
of your now-repeated statements were false, but you insist on them, and
you don't provide any arguments to support your position that
contradicts POSIX explicit statements.  From that, I conclude it's
pointless for me to spend any more time on it.  Don't expect an answer
from me on the other subthread where that discussion is the focus.

>> >> it's combining it with other calls in MT-Unsafe ways that would
>> >> be, and one way to perform such combination is to perform this
>> >> sort of unexpected inlining that LTO on a static glibc might end
>> >> up performing.

>> > Can you elaborate?

>> I'm not sure what you want me to elaborate on,

> I couldn't understand "it's combining it with other calls in MT-Unsafe
> ways that would be".  (And I still can't understand that part when
> looking at what you said below.)

foo () {
  ...
  save = signal(SIGWHATEVER, myhandler);
  ... /* meanwhile, another thread modifies the handler */
  signal(SIGWHATEVER, save); // oops
  ...
}

Unless the potential of dropping a signal handler concurrently set by
another thread was part of the specified behavior for foo, the above
sequence in the implementation of foo is not safe, even though the two
visible functions calls above are individually atomic, and MT-Safe.

>> Sorry, the âI agreeâ above was misleading.  I only agreed that it would
>> be better to change this to atomic memory accesses.  Although, on second
>> thought, I'm not even convinced this would be an improvementto the cases
>> at hand, for it would force unnecessary synchronization.

> If any of the data is modified concurrently, we must use atomic
> accesses; otherwise, there is no guarantee that we won't read garbage

I'm not familiar with any hw memory model in which an unsynchronized
single-word read could actually read garbage, rather than a value that
may be outdated.

> I'm not aware of any architecture that would use something special for
> relaxed-MO atomic loads/stores that are not the same instructions used
> for normal loads/stores

I can imagine architectures with lazy distributed cache invalidation
that would check with other caches for pending invalidations for an
update only on atomic-acq reads, but not on regular reads.

> The compiler can reload from memory,

It can't.  It's only one access.

> It could decide to split a 64b load into two 32b loads.

It can't, it's a single word load.

> There were GCC bugs in this area that were revealed by fuzz testing, so
> I'm not making that up.

That would be a compiler bug.  Compiler bugs can cause misbehavior.  But
in these cases, it's the compiler that's wrong, not the application (or
the library) that it miscompiles.  Under the language model it ought to
implement, aligned-word-single-read is safe.

[snipped discussion whose repetition I refuse to take part of]

>> sin() doesn't have synchronization either, and it's perfectly MT-Safe.
>> Why should it synchronize with any other threads?

> Your argument is backwards.  You say that there can be MT-Safe functions
> that don't need shared-memory synchronization because they don't access
> shared memory.  Fine.  But how does that imply that functions that use
> shared memory don't need shared-memory synchronization?

It doesn't.  A single counter-example is enough to disprove what
purports to be a general statement.

What begs proving is whether POSIX mandates synchronization for any
case.  It offers synchronization operations and mutexes as examples of
what an implementation might internally use to achieve safety, but the
only interfaces for which synchronization is mandatory are the ones used
for synchronization (mutexes, locks and condition variables)


>> I remember there were various other read-word-and-apply-bitmask macros
>> and functions for which the same reasoning applied.

> Okay.  Were these internal macros, or ones part of the external
> interface?

I can't say they were all internal, but there aren't very many macros
that are part of the external interface.  Those that come to mind are
the non-wide ctype macros, that access read-only memory, and the file
type macros for stat structs, that would require user synchronization of
the stat structs in the unlikely case of inter-thread use.

> As an expert in the field

You know what?  Maybe you're an expert in concurrency and memory models,
and that twists your view of MT-Safe under the looks-like-a-nail
principle.  This possibility appears to fit the obsevable behavior.

> I agree when splitting into "core safe" and "extended safe".  Maybe put
> that into the docs?

I don't want people to get the wrong idea that there's an extended
safe.  That only complicates the model.  See, you got that nonsense out
of earlier misphrasing, and see how hard it is to take that out of your
mind now!

>> > if you need to have these requirements to make a generally MT-Unsafe
>> > function MT-Safe under these requirements, then this is equivalent to a
>> > constraint on an MT-Safe function, right?
>> 
>> Sorry, I can see it that way.

> Good! ;)

Hey, where did my negation in the sentence above go?

Seriously, I meant I can*not* see it that way.

Apologies for the typo.  Take that as evidence that I find this other
sub-topic of the discussion a waste of time and I'm rushing my writing
about it out, evidently without enough care and attention :-(

> I think splitting into core-safe (or, safe without constraints),

Stop right there!

That's the model I want to describe.  No complications, no exceptions.


Now, if you really want to call such and such unsafe functions, here's
what you have to do.  That's not part of the model.  That's an
exception.  I don't want to introduce exceptions; they're complications
and distractions.  KIS, Sir ;-)

> That works too, because you split it into core-safe, extended-safe,
> unsafe, and let readers know that extended-safe is with constraints.
> That's what I was looking for.

Well, that's what I have now.

Hmm...  I wonder if this was the proposed change I made in my local copy
and quoted something, but you then replied you couldn't quite fit it in
the whole with those the snippets.  If that's so, maybe it's time for me
to post another copy of the patch.  Will do...

-- 
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]