Email List: Xaustin-group-lX
[All Lists]

Re: [Fwd: C Language Thread API]

To: Nick Stoughton <nick@xxxxxxxxxx>
Subject: Re: [Fwd: C Language Thread API]
From: Hallvard B Furuseth <h.b.furuseth@xxxxxxxxxxx>
Date: Tue, 12 Aug 2008 15:16:36 +0200
Cc: austin-group-l@xxxxxxxxxxxxx
References: <1218473241.3586.3.camel@amstaff2.msbit.com><20080811181238.GD11392@xxxxxx><48A16DF1.5020007@xxxxxx>
Not sure if most of this posting really belongs here rather than in
comp.std.c, but since I saw it here:

Ted Baker wrote:
> Here we go again, with more proliferation of
> similar-but-not-identical standards...  I skimmed through the
> document at the cited URL.  It is so close to POSIX threads that I
> wondered what is the justification for introducing yet another set
> of names.  (...)

While I don't know why they are doing it this way, I can see one
advantage:  The C language and memory model will finally acknowledge
the existence of threads.  It could do that without providing an API,
and maybe suggest these primitives as a theoretical way to implement
threading.  However I'd suspicious of such a purely theoretical model.
If it doesn't get some real-life exposure in its own right, design
bugs and other problems don't get detected as easily.

OTOH - I found a strong criticism of Posix-like threading in:
  "Why POSIX Threads Are Unsuitable for C++" by Nick Mclaren:
  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1940.pdf
I didn't understand all of it, and I don't know if the current proposal
is loose enough to accommodate his objections or if he lost the debate.
Statements like "almost all modern, scalable, parallel applications use
MPI" (as in OpenMP rather than pthreads) looked a bit damning...

David Butenhof writes:
> I have to agree with Ted.  Perhaps the weakest part of this
> pseudo-generic wrapper package is that it lacks even an extension
> mechanism to change any semantic attributes of threads before starting
> them; (...)

Another extension mechanism I missed is that pthread functions return
errno values (which the implementation can invent), while this one only
returns a few predefined error values.  If none of the three defined
error values are suitable, why not let the functions return 'any other
(positive?) value' instead of 'thrd_error'?  That'd also allow - but not
require - an implementation to return errno values, and to define the
thrd_* error values to 0, ENOMEM, ETIMEDOUT and EBUSY.  Incidentally, it
looks to me like these functions as written must not return EINTR - they
must instead loop.

I guess the functions could set errno when returning thrd_error, but it
seems messy to both return an error value beyond success/failure and set
errno.  One should be enough.

> Of course the "xtime" thing and thrd_sleep() is just POSIX timespec and
> nanosleep(). Adding a C language facility equivalent to 'struct
> timespec' will, inevitably, end up with a similar but semantically
> unrelated data type that needs to be converted and interpreted in any
> real application, causing pain for innumerable developers for many years
> to come. While I see the motivation that drives messes like this, I
> don't like it.

Couldn't xtime be defined so that POSIX can state that xtime must be a
typedef for struct timespec?

The current xtime spec is wrong for C:  It says sec and nsec are ints.
But if int is 16-bit, it can hold neither nanoseconds nor the current
time in seconds.  It's not necessarily a Dinkum bug - maybe their
implementation does not attempt to support 16-bit int.


Other notes about n1287:

The type names 'once_flag' and 'xtime' lack a '_t' suffix.  I can well
imagine at least the former could conflict with variable names.

For that matter, depending on how widely this API is expected to be
used, I wonder if the functions and types should all get a 'thrd_'
prefix, to reduce namespace pollution in programs that do use them.

Why do thrd_abort() and thrd_sleep() have thrd_ prefixes?  What is
thread-related about those functions?



There is no equivalent of PTHREAD_<COND/MUTEX>_INITIALIZER.  Maybe they
could be made optional - so programs that want them can do #ifdef
MTX_INIT/CND_INIT?  Then implementations where cnd_init/mtx_init use
resources, can choose to not #define these flags - and thus ensure that
the first call to mtx_lock() on the mutex will not fail due to resource
limits in the implicit "if (mutex == MTX_INIT) { mtx_init() for real }".

> Memory Visibility
> "There are three times at which changes made to memory by one thread
> are guaranteed to be visible in another thread:
> [...thread creation and mutex use...]"

By itself this is misleading, since other parts of the document goes on
to say:

> "The condition variable functions use a mutex internally; when a
> thread returns from a wait function any changes made to memory by
> threads that called a wait function or a notify function before the
> return will be visible to the caller."
> (...)
> "The function call_once uses a mutex internally; when it returns any
> changes made to memory by the once function will be visible to the
> caller."

I see no reason why the document should state how operations works
internally.  It'd be cleaner to list the actual operations that affect
memory visibility up front.

> Once Functions

This section (as well as the POSIX spec) should specify that if several
threads call call_once/pthread_once in parallel with the same once_flag,
the ones not calling the once function will wait - so that the once
function call will have been completed when the threads proceed.

> mtx_init
> (...)
> The function creates a mutex object with properties indicated by type,
> which must have one of the six values

This and the function specs would be more readable if described in terms
of a bitmask mtx_something (mtx_plain|mtx_timed|mtx_try) | mtx_recursive.

For that matter, if mtx_timed is defined as (mtx_try | something) != 0,
then mtx_trylock would only need to mention that it needs the mtx_try
flag - it need not mention mtx_timed.

>   * mtx_timed -- for a non-recursive mutex that supports timeout

That should be "timeout as well as test-and-return", according to the
mtx_trylock() spec.  Also fix the 'mtx_timed' header.

Incidentally, I suggest to spell test-and-return with hyphens.  That
"and" can be a little confusing in the middle of a sentence, if printed
on a device which does not preserve underlining of "test and return".

> #define TSS_DTOR_ITERATIONS <integer constant expression>

Maybe this should be a allowed to expand to a non-constant expression,
so the implementation is free to make it a user-settable resource limit.

-- 
Hallvard

<Prev in Thread] Current Thread [Next in Thread>