yyyyyyyy@xxxxxxxxxx wrote:
Defect report from : Alexander Terekhov , IBM
(Please direct followup comments direct to yyyyyyyyyyyyyy@xxxxxxxxxxxxx)
@ page 0 line 0 section XBD 4.10 Memory Synchronization comment {xbd-4.10-sucks-2006-02-27}
Problem:
Edition of Specification (Year): 2004
Defect code : 3. Clarification required
Application programmers must <XRAT-quote> use synchronization primitives
correctly to ensure that modifications to a location in memory are
ordered with respect to modifications and/or access to the same location
in other threads. Access to read-only data need not be synchronized. The
resulting program is said to be data race-free. </XRAT-quote>
Current normative wording in XBD 4.10 miserably fails to deliver on that
premise. It doesn't specify how to use synchronization primitives
correctly to ensure that modifications to a location in memory are
ordered with respect to modifications and/or access to the same location
in other threads, to begin with.
In its current form XBD 4.10 is decisively meaningless. The unfortunate
use of not defined term "memory synchronization" is the source of endless
confusion and misinterpretation of the intended meaning of XBD 4.10 by
many folks -- the standards working group including.
It's not at all meaningless -- it simply doesn't mean what you want it
to mean. (It doesn't mean what WE wanted it to mean, either, but that's
a different matter entirely.) I'm afraid your attempts don't really mean
a lot more, but it is a start.
Action:
1. Rename XBD 4.10 title to "Data race-free" or something (without
using words "memory synchronization").
2. Replace its body with something along the lines of
-----
Applications shall ensure that access to any memory location by more
than one thread is restricted such that no thread can read or modify
a memory location while another thread of control may be modifying it.
Applications shall use functions listed below that synchronize thread
execution and ensure that modifications to locations in memory are
ordered with respect to accesses to the same memory locations in other
threads. There is a happens-before inter-thread ordering with respect
to preceding (in program and inter-thread order) modifications of
memory locations in
"Happens-before" is completely undefined and not at all intuitive. It's
certainly less intuitive than the original POSIX "memory
synchronization" with which you have so much trouble. Define what you
mean, don't just throw out words.
a thread calling pthreads_create() and accesses to modified memory
locations in the created thread;
a thread calling fork() and accesses to modified memory locations
in the initial thread of the created process;
a terminated thread and accesses to modified memory locations in
another thread in the same process after that thread returns from
pthread_join() joining the terminated thread, or in another thread
in a parent process after that thread returns from wait() or
waitpid() observing terminated status of a child process;
a thread calling sem_post() on a specified semaphore and accesses
to modified memory locations in another thread after that thread
calls sem_wait() or sem_trywait() or sem_timedwait() and
locks the same semaphore unlocked by the calling thread, or
another thread observes the incremented semaphore value of the
same semaphore by calling sem_getvalue();
a thread calling sem_wait() or sem_trywait() or sem_timedwait()
decrementing semaphore value of a specified semaphore and accesses
to modified memory locations in another thread after that thread
observes the decremented semaphore value of the same semaphore
using sem_getvalue();
< XSI IPC semas... >
Don't propose that someone else finish your wording, Alexander. You've
been guilty of this in the past, and it's just sloppy. If you're not
willing to take on the work of making your proposal, don't bother.
< realtime signals? sigvalue is a union with pointer... >
Same here.
a thread calling pthread_spin_unlock() on a specified spin lock
and accesses to modified memory locations in another thread
after that thread calls pthread_spin_lock() or
pthread_spin_trylock() and locks the same spin lock unlocked by
the calling thread;
Two distinct "calling threads" here (and in your subsequent cases) --
this needs tighter wording.
a thread calling pthread_rwlock_unlock() on a specified read-
write lock releasing a write lock and read accesses to modified
memory locations in another thread after that thread acquires a
read lock using pthread_rwlock_rdlock() or
pthread_rwlock_timedrdlock() or pthread_rwlock_tryrdlock() on
the same read-write lock unlocked by the calling thread;
a thread calling pthread_rwlock_unlock() on a specified read-
write lock releasing a write lock and read/write accesses to
modified memory locations in another thread after that thread
acquires a write lock using pthread_rwlock_timedwrlock() or
pthread_rwlock_trywrlock() or pthread_rwlock_wrlock() on
the same read-write lock unlocked by the calling thread;
a thread calling pthread_mutex_unlock() on a specified mutex
and accesses to modified memory locations in another thread
after that thread calls pthread_mutex_lock() or
pthread_mutex_timedlock() or pthread_mutex_trylock() and locks
the same mutex unlocked by the calling thread or when another
thread locks the same mutex unlocked by the calling thread
and returns from a call to pthread_cond_wait() or
pthread_cond_timedwait();
a thread calling pthread_cond_wait() or pthread_cond_timedwait()
and accesses to modified memory locations in another thread
after that thread calls pthread_mutex_lock() or
pthread_mutex_timedlock() or pthread_mutex_trylock() and locks
the same mutex unlocked by the calling thread or when another
thread locks the same mutex unlocked by the calling thread
and returns from a call to pthread_cond_wait() or
pthread_cond_timedwait();
a thread calling pthread_barrier_wait() on a specified barrier
and accesses to modified memory locations in another thread
after that thread returns from pthread_barrier_wait() call on
the same specified barrier on the same or later barrier cycle;
"barrier cycle" is not defined. In any case, no thread shall return from
a wait in a given "cycle" until all have arrived at the barrier, and no
thread can return from a subsequent cycle prior to that... so there's no
point in trying to be so ambitious here. When threads participating in a
barrier return from pthread_barrier_wait(), they shall have a common
view of memory.
a thread calling pthread_once() on a specified pthread_once_t
object returning from a specified init_routine and accesses to
modified memory locations in another thread after that thread
returns from pthread_once() on the same pthread_once_t object.
Functions listed above and also pthread_cond_signal() and
pthread_cond_broadcast() are all side effects.
You'll need to explain this statement a good deal better.
Conforming applications are said to be data race-free.
-----
Generally, I concur with the intent; it is a big improvement on prior
attempts you've made, but still needs a lot more editing work to clarify
and remove ambiguities in your references.
You (and everyone) also needs to keep in mind that this is an enormous
semantic change, however "good" it might be. For example, it finally
codifies our original INTENT that memory visibility be tied to
individual synchronization objects rather than global. POSIX currently
says that if threadA locks or unlocks mutexA and threadB locks or
unlocks mutexB, they have synchronized their view of memory -- because
it's all defined in terms of OPERATIONS rather than OBJECTS. I would
hope no code depended on that more general interpretation; but if any
did, they could be broken by a strict implementation of your change.
(Such applications are sloppy at best, and I don't mind breaking them;
but some will mind, and probably should.)
david.butenhof.vcf
Description: Text Data
|