Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

harmonization(?) of threading interfaces between POSIX/SUS and C1X

13 views
Skip to first unread message

Ersek, Laszlo

unread,
Jul 30, 2010, 8:17:55 AM7/30/10
to
Hi,

just out of curiosity, are there plans (and if so, what plans) to
harmonize the threading interfaces described in N1494 [0] and POSIX [1]?

More precisely, I suppose chapter 7.25 in C1X was constructed with an eye
on POSIX threads in the first place. I'd like to read about the process
and design principles behind C1X 7.25. For example, once C1X becomes a
standard and POSIX/SUS is (presumably) rebased on it, what will happen to
the pthreads API? And how will the two APIs interoperate?

This seems to be an interesting situation where features of the "derived
standard" are seeping through to the next version of the "base standard",
but under different names.

I'm sending this to both austin-group-l and comp.std.c.

Thank you very much,
lacos

[0] http://www.open-std.org/jtc1/sc22/wg14/www/projects#9899
[1] http://www.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html

lawrenc...@siemens.com

unread,
Jul 30, 2010, 12:42:55 PM7/30/10
to
Ersek, Laszlo <la...@caesar.elte.hu> wrote:
>
> More precisely, I suppose chapter 7.25 in C1X was constructed with an eye
> on POSIX threads in the first place. I'd like to read about the process
> and design principles behind C1X 7.25.

The main design goal was to come up with a generic, basic API that could
be easily implemented as a thin layer on top of popular existing threads
implementations, most notably POSIX threads and Windows threads.
--
Larry Jones

Let's just sit here a moment... and savor the impending terror. -- Calvin

Ersek, Laszlo

unread,
Jul 30, 2010, 2:18:53 PM7/30/10
to
On Fri, 30 Jul 2010, lawrenc...@siemens.com wrote:

> Ersek, Laszlo <la...@caesar.elte.hu> wrote:
>>
>> More precisely, I suppose chapter 7.25 in C1X was constructed with an eye
>> on POSIX threads in the first place. I'd like to read about the process
>> and design principles behind C1X 7.25.
>
> The main design goal was to come up with a generic, basic API that could
> be easily implemented as a thin layer on top of popular existing threads
> implementations, most notably POSIX threads and Windows threads.

Thank you.
lacos

Robert Gamble

unread,
Jul 30, 2010, 5:29:43 PM7/30/10
to
On Jul 30, 12:42 pm, lawrence.jo...@siemens.com wrote:
> Ersek, Laszlo <la...@caesar.elte.hu> wrote:
>
> > More precisely, I suppose chapter 7.25 in C1X was constructed with an eye
> > on POSIX threads in the first place. I'd like to read about the process
> > and design principles behind C1X 7.25.
>
> The main design goal was to come up with a generic, basic API that could
> be easily implemented as a thin layer on top of popular existing threads
> implementations, most notably POSIX threads and Windows threads.

Just out of curiosity, who is the target audience for the C Threads
API? Who is pushing for this so hard that the committee feels
compelled to focus their efforts on something like this when much
richer and widely used APIs, such as POSIX threads, already exists? I
can't imagine anyone using this API instead of something like the more
established/mature/featureful pthreads, etc. if they have access to
it, and if they don't I don't see this API being able to provide the
support needed for serious multi-threaded applications. Who is going
to benefit from this?

--
Robert Gamble

Ersek, Laszlo

unread,
Jul 30, 2010, 7:33:08 PM7/30/10
to
On Fri, 30 Jul 2010, Robert Gamble wrote:

> Just out of curiosity, who is the target audience for the C Threads API?
> Who is pushing for this so hard that the committee feels compelled to
> focus their efforts on something like this when much richer and widely
> used APIs, such as POSIX threads, already exists? I can't imagine
> anyone using this API instead of something like the more
> established/mature/featureful pthreads, etc. if they have access to it,
> and if they don't I don't see this API being able to provide the support
> needed for serious multi-threaded applications.

I do. You've got mutexes and condvars, timed functions, call_once, detach
and join, and tss. That should cover even more than the basics. With
mutexes and condvars, you can implement semaphores and read-write locks,
for example. Didn't think of barriers before, but probably those as well.
What are you missing? (-> comp.programming.threads, perhaps?)


> Who is going to benefit from this?

Developers writing bare-bones standard C code for embedded platforms with
multiple cores, I presume. At least a bigger chunk of the code can be made
portable.

Also, I suppose a multi-threaded application targeted at both Windows and
POSIX abstracts out a minimal threading interface, with as few features as
it can get away with, then implements that interface for each platform
separately. The C1X threads API could make such an effort unnecessary or
easier.

Lastly, threads-related questions in c.l.c wouldn't be OT anymore :)

lacos
(too tired again; sorry for any nonsense)

Miles Bader

unread,
Jul 31, 2010, 3:23:35 AM7/31/10
to
Robert Gamble <rgam...@gmail.com> writes:
> Just out of curiosity, who is the target audience for the C Threads
> API? Who is pushing for this so hard that the committee feels
> compelled to focus their efforts on something like this when much
> richer and widely used APIs, such as POSIX threads, already exists? I
> can't imagine anyone using this API instead of something like the more
> established/mature/featureful pthreads, etc.

Eh?

std::thread is actually quite a nice little API for non-demanding thread
usage, is very simple to use, and has the one generally needs (mutexes,
condition-variables).

The programming model is basically that of existing practice, so it is
well-proven and familiar, but also has a small amount of C++-specific
polish which make it a bit easier to use and less error-prone (e.g., the
use of lock-guards).

Since many apps would need a portability layer _anyway_ (to account for
pthreads/windows), why not use std::thread for that (or boost::thread,
which is basically a superset, for compilers currently without c++0x
support)?

[I recently added multi-threading to an app using std::thread /
boost::thread, and found it very nice -- basically exactly what I
wanted.]

-Miles

--
Circus, n. A place where horses, ponies and elephants are permitted to see
men, women and children acting the fool.

Miles Bader

unread,
Jul 31, 2010, 10:15:46 AM7/31/10
to
Ah, sorry, I somehow thought this thread was about std::thread in C++0x,
but upon re-reading the post, it seems to be about something else...

My apologies.

-Miles

--
Run away! Run away!

Dag-Erling Smørgrav

unread,
Aug 2, 2010, 9:19:46 AM8/2/10
to
"Ersek, Laszlo" <la...@caesar.elte.hu> writes:

> Robert Gamble <rgam...@gmail.com> writes:
> > Who is going to benefit from this?
> Developers writing bare-bones standard C code for embedded platforms
> with multiple cores, I presume. At least a bigger chunk of the code
> can be made portable.
>
> Also, I suppose a multi-threaded application targeted at both Windows
> and POSIX abstracts out a minimal threading interface, with as few
> features as it can get away with, then implements that interface for
> each platform separately. The C1X threads API could make such an
> effort unnecessary or easier.

The Windows and POSIX threading models are so similar that you can
implement most of the threads POSIX API as a set of macros or very short
inline functions on top of the Windows threads API. Likewise, I suspect
that most C implementations will implement the C threads API as a set of
macros or short inline functions on top of their native (POSIX or
Windows) API, rather than the other way around. I also suspect that
most developers will simply ignore it. It is still a very useful
addition to C, not because we need another API, but because we need
clear answers about how C handles or should handle concurrency.

DES
--
Dag-Erling Smørgrav - d...@des.no

William Ahern

unread,
Aug 3, 2010, 5:53:31 PM8/3/10
to
Dag-Erling Sm?rgrav <d...@des.no> wrote:
> "Ersek, Laszlo" <la...@caesar.elte.hu> writes:
> > Robert Gamble <rgam...@gmail.com> writes:
> > > Who is going to benefit from this?
> > Developers writing bare-bones standard C code for embedded platforms
> > with multiple cores, I presume. At least a bigger chunk of the code
> > can be made portable.
> >
> > Also, I suppose a multi-threaded application targeted at both Windows
> > and POSIX abstracts out a minimal threading interface, with as few
> > features as it can get away with, then implements that interface for
> > each platform separately. The C1X threads API could make such an
> > effort unnecessary or easier.

> The Windows and POSIX threading models are so similar that you can
> implement most of the threads POSIX API as a set of macros or very short
> inline functions on top of the Windows threads API.

The Windows threading API is atrocious. From the MSDN documentation:

Before the threads of the process can use it, initialize the
critical section by using the InitializeCriticalSection or
InitializeCriticalSectionAndSpinCount function.

Thus, in order to use a mutual exclusion primitive you must first roll your
own mutual exclusion primitive! An especially pedantic person might conclude
that Windows doesn't even provide threading primtives, per se.

A snippet from some of my code:

#if _WIN32
volatile LONG init;

do {
switch (init = InterlockedCompareExchange((LONG *)&arc4.mux.init, 1, 0)) {
case 2: /* initialized already. */
break;
case 1: /* try again. */
Sleep(1);

break;
case 0: /* must initialize. */
InitializeCriticalSection(&arc4.mux.cs);

InterlockedExchange((LONG *)&arc4.mux.init, 2);

break;
}
} while (1 == init);

EnterCriticalSection(&arc4.mux.cs);
#else
pthread_mutex_lock(&arc4.mux);
#endif

Marcin Grzegorczyk

unread,
Aug 4, 2010, 5:45:00 PM8/4/10
to

At the risk of getting seriously off-topic, I'll say I think you're
doing things in a spectacularly wrong way. Unless there's a good reason
for not doing so, you should call InitializeCriticalSection() before you
create any threads that will need the critical section. It's not that
much different from how you initialize POSIX mutexes, except that you
have the convenient static PTHREAD_MUTEX_INITIALIZER so you may not have
to call pthread_mutex_init() explicitly.

(To bring this discussion back in the general vicinity of this
newsgroup's topic: Win32's critical sections are recursive but not
timed, and IIRC did not support test and return before Windows 2000;
Win32's mutexes are more heavyweight but do support timed wait. Neither
can be used without a call to the appropriate initialization function,
which I guess is one of the reasons C1X has mtx_init() but no static
mutex initialization.)
--
Marcin Grzegorczyk

William Ahern

unread,
Aug 5, 2010, 4:27:45 PM8/5/10
to
Marcin Grzegorczyk <mgrz...@poczta.onet.pl> wrote:
<snip>

> At the risk of getting seriously off-topic, I'll say I think you're
> doing things in a spectacularly wrong way. Unless there's a good reason
> for not doing so, you should call InitializeCriticalSection() before you
> create any threads that will need the critical section. It's not that
> much different from how you initialize POSIX mutexes, except that you
> have the convenient static PTHREAD_MUTEX_INITIALIZER so you may not have
> to call pthread_mutex_init() explicitly.

Yes, except how do you do that portably for a global mutex in a library that
cannot be explicitly initialized by the caller? In this case, it's an
arc4random implementation which is normally provided by libc.

For Windows development this issue isn't pressing because the fact of the
matter is that C++ dominates on Windows, and it's easy enough to use static
constructors (or whatever the term of art is in C++). C has no such
facilities.

> (To bring this discussion back in the general vicinity of this
> newsgroup's topic: Win32's critical sections are recursive but not
> timed, and IIRC did not support test and return before Windows 2000;
> Win32's mutexes are more heavyweight but do support timed wait. Neither
> can be used without a call to the appropriate initialization function,
> which I guess is one of the reasons C1X has mtx_init() but no static
> mutex initialization.)

That's a shame.

Dag-Erling Smørgrav

unread,
Aug 6, 2010, 10:13:25 AM8/6/10
to
William Ahern <wil...@wilbur.25thandClement.com> writes:
> Yes, except how do you do that portably for a global mutex in a
> library that cannot be explicitly initialized by the caller?

You initialize your library on first call. Use an atomic test-and-set
to check whether the initialization routine has already been called.

Wojtek Lerch

unread,
Aug 6, 2010, 10:45:57 AM8/6/10
to
"Dag-Erling Smørgrav" <d...@des.no> wrote in message
news:8639ur9...@ds4.des.no...

> William Ahern <wil...@wilbur.25thandClement.com> writes:
>> Yes, except how do you do that portably for a global mutex in a
>> library that cannot be explicitly initialized by the caller?
>
> You initialize your library on first call. Use an atomic test-and-set
> to check whether the initialization routine has already been called.

That's not enough. You also need to check if another thread is in the
middle of the initialization routine, and wait for it to finish.


sfuerst

unread,
Aug 6, 2010, 2:05:36 PM8/6/10
to
On Aug 5, 1:27 pm, William Ahern <will...@wilbur.25thandClement.com>
wrote:

Actually... since Vista was released it is possible to create a
PTHREAD_MUTEX_INITIALIZER that uses critical sections. The problem
was that the critical section functions could fail when they tried to
allocate memory for their debug information. Microsoft realized that
applications don't actually check for these basic threading functions
to fail, since there is often very little they can do except retry the
operation. So they changed the interfaces to never fail, and instead
internally mark the debug state as "not allocated yet" if allocation
doesn't work. Thus you can manually put the critical section into
this undocumented state in the initializer macro and everything works
as it should.

The timedwait functionality can be obtained by using
WaitForSingleObject() on the embedded semaphore within the critical
section object. I've written an article showing how you can use these
undocumented interfaces (together with others) to implement the
pthreads API relatively efficiently on (modern) Microsoft windows:
http://locklessinc.com/articles/pthreads_on_windows/

Of course the Windows API isn't quite as rich as the posix one since
only a single type of mutex is supported... but if you are going to
interoperate with other libraries, that single type is exactly what
they are using.

Steven

Robert Gamble

unread,
Aug 11, 2010, 9:09:24 AM8/11/10
to

Why stop at threading? Why not add a bare-bones networking API to
Standard C? All of your arguments work as well for that as they do
for threading. Standards exist for a reason and there are already
perfectly good, widely accepted standards for threading. Adding a new
one to the mix doesn't add any real value and just serves to add the
kind of bloat (that nobody is going to use anyway) that C99 did. I
thought it was widely accepted, even among many committee members,
that C99 overstepped the bounds of what the industry was looking for
which resulted in lackluster acceptance and sparse support even after
10 years. I would think that in recognizing this the committee would
be a little more conservative about where they focus their attention,
or is there a large community outcry for a threads API in Standard C
that I have failed to notice?

--
Robert Gamble

Dag-Erling Smørgrav

unread,
Aug 11, 2010, 10:10:34 AM8/11/10
to
Robert Gamble <rgam...@gmail.com> writes:
> Why stop at threading? Why not add a bare-bones networking API to
> Standard C? All of your arguments work as well for that as they do
> for threading. Standards exist for a reason and there are already
> perfectly good, widely accepted standards for threading. Adding a new
> one to the mix doesn't add any real value and just serves to add the
> kind of bloat (that nobody is going to use anyway) that C99 did.

Having a threading API means having a threading model, which means that
the upcoming standard defines the behavior of types, operators and
library functions in threaded programs. I find that very valuable, even
if I'll probably never use the threading API itself.

Ersek, Laszlo

unread,
Aug 11, 2010, 10:25:08 AM8/11/10
to

Marcin Grzegorczyk

unread,
Aug 13, 2010, 3:21:15 PM8/13/10
to
Ersek, Laszlo wrote:
[snip]

> See also the similarly titled thread on austin-group-l:
>
> https://www.opengroup.org/sophocles/show_archive.tpl?listname=austin-group-l
>
>[...]
> https://www.opengroup.org/sophocles/show_mail.tpl?CALLER=show_archive.tpl&source=L&listname=austin-group-l&id=14336
>[...]

Somebody should tell David Butenhof that he's misinterpreting the C1X
draft. Per chapter 4, if a 'shall' that appears outside of a constraint
or runtime-constraint (and there are none of those in the library,
except for Annex K) is violated, the behaviour is undefined -- and, as
you (Laszlo) correctly said, an implementation (or a derivative
standard) is free to turn any undefined behaviour into a defined one.
In particular, AFAICT, nothing in the current draft forbids an
implementation to have a single (timed and recursive) underlying mutex
type, and ignore all the mtx_* flags. (Of course, a strictly conforming
program could never take advantage of that.)
--
Marcin Grzegorczyk

Ersek, Laszlo

unread,
Aug 13, 2010, 4:45:18 PM8/13/10
to
On Fri, 13 Aug 2010, Marcin Grzegorczyk wrote:

> Per chapter 4, if a 'shall' that appears outside of a constraint or
> runtime-constraint (and there are none of those in the library, except

> for Annex K) is violated, the behaviour is undefined -- and [...] an

> implementation (or a derivative standard) is free to turn any undefined

> behaviour into a defined one. [...] (Of course, a strictly conforming

> program could never take advantage of that.)

Thanks!
lacos

(PS: I hope my liberal editing kept the intent of your message intact.)

Richard Bos

unread,
Aug 14, 2010, 8:50:54 AM8/14/10
to
Robert Gamble <rgam...@gmail.com> wrote:

> On Jul 30, 7:33=A0pm, "Ersek, Laszlo" <la...@caesar.elte.hu> wrote:
> > Also, I suppose a multi-threaded application targeted at both Windows and
> > POSIX abstracts out a minimal threading interface, with as few features as
> > it can get away with, then implements that interface for each platform
> > separately. The C1X threads API could make such an effort unnecessary or
> > easier.

> Why stop at threading? Why not add a bare-bones networking API to


> Standard C? All of your arguments work as well for that as they do
> for threading.

For one, no, they don't. A bare-bones threading API is (presumably; I
haven't seen the details) quite possible, but I have seen enough wildly
different networking setups to realise that a bare-bones networking API
consists of:

_Bool std_network_avail();
returns true if some form of networking is available; false if not.

and no more.

Richard

0 new messages