Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Trivial C11 threads.h wrapper (public domain)

Reply
Thread Tools

Trivial C11 threads.h wrapper (public domain)

 
 
John Tsiombikas
Guest
Posts: n/a
 
      09-27-2012
Hello everyone! It's been a long time since I was last on usenet

I was anxious to use the new standard C11 threading features, instead of
platform-specific APIs, but unfortunately my system libc (GNU libc) does
not implement that bit that yet.
So, I wrote a trivial C11 thread wrapper over POSIX threads, and
released it in the public domain just in case anyone is itching to use
standard C threading in a new project just like me:
https://github.com/jtsiomb/c11threads

The wrapper is so thin, I didn't think it made sense to make a proper
library out of it, so it's just a header file with "static inline"
functions. Drop it in your project, link with pthread and you're good to
go.

Disclaimer: I used a draft of the C11 standard while writting this code,
since I don't actually have the final document. Feel free to notify me
of any glaring discrepancies or omissions.

Cheers!

--
John Tsiombikas
http://nuclear.mutantstargoat.com/
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-27-2012
John Tsiombikas <> writes:
[...]
> Disclaimer: I used a draft of the C11 standard while writting this code,
> since I don't actually have the final document. Feel free to notify me
> of any glaring discrepancies or omissions.


The latest draft I'm aware of is
http://www.open-std.org/jtc1/sc22/wg...docs/n1570.pdf
I think it's nearly identical to the released standard.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
John Tsiombikas
Guest
Posts: n/a
 
      09-27-2012
On 2012-09-27, Keith Thompson <kst-> wrote:
> John Tsiombikas <> writes:
> [...]
>> Disclaimer: I used a draft of the C11 standard while writting this code,
>> since I don't actually have the final document. Feel free to notify me
>> of any glaring discrepancies or omissions.

>
> The latest draft I'm aware of is
> http://www.open-std.org/jtc1/sc22/wg...docs/n1570.pdf
> I think it's nearly identical to the released standard.
>


Thanks, that's a bit more recent than the one I had. I'll go through
them and see if I can spot any relevant differences.

--
John Tsiombikas
http://nuclear.mutantstargoat.com/
 
Reply With Quote
 
Markus Elfring
Guest
Posts: n/a
 
      09-27-2012
> So, I wrote a trivial C11 thread wrapper over POSIX threads, and
> released it in the public domain just in case anyone is itching to use
> standard C threading in a new project just like me:


I have looked at your source file.
https://github.com/jtsiomb/c11thread...4/c11threads.h

I suggest to consider the following implementation details a bit more.
1. Would you like to provide a "typedef" for each enumeration?

2. How do you think about to complete error detection and corresponding
exception handling?
2.1 Mapping of error codes from the POSIX thread interface to the values that
are specified by the current standard for the C programming language.
2.2 pthread_mutexattr_init/destroy

Regards,
Markus
 
Reply With Quote
 
John Tsiombikas
Guest
Posts: n/a
 
      09-27-2012
On 2012-09-27, Lorenzo Beretta <> wrote:
> I haven't read it carefully enough to count as proofreading... most of
> it seem to make sense, except for a couple of things:
> 1. pthread_create can return EAGAIN, isn't it almost the same as thrd_nomem?


I though about that for a bit while writting it, but after reading the
pthreads manpage and the C standard a couple of times, I decided it's
probably not the same error, and I thought it would be best to just
leave thrd_nomem out. Might be wrong, I'll go through them again.

> 2. pthread_mutex_timedlock sucks badly -- even microsoft got it right!
> Try the following program and try not to scream when you realize
> *why* it's not doing what you'd expect
>
> ...
> const int s = 5;
> ...
> t.tv_nsec = 0;
> t.tv_sec = s;
> /* puke! */
> printf("timed_lock(%d) = %d\n", s, pthread_mutex_timedlock(&m, &t));


*gasp* ... it's absolute time ?! I must admit I never used
timedlocks...

I suppose that makes it easier to ask it to try locking the mutex
until next friday at 3 o'clock or something


--
John Tsiombikas
http://nuclear.mutantstargoat.com/
 
Reply With Quote
 
John Tsiombikas
Guest
Posts: n/a
 
      09-27-2012
On 2012-09-27, Markus Elfring <> wrote:
>
> I have looked at your source file.
> https://github.com/jtsiomb/c11thread...4/c11threads.h
>
> I suggest to consider the following implementation details a bit more.
> 1. Would you like to provide a "typedef" for each enumeration?


Would I *like* to do that? probably not, but it's not a matter of
preference. Unless I'm much mistaken, the C11 standard dictates int
as the type of the second argument of mtx_init (where all the mtx_
enumerations go), and as the return of all functions that need to
indicate success or failure (thrd_ enumerations).

> 2. How do you think about to complete error detection and corresponding
> exception handling?
> 2.1 Mapping of error codes from the POSIX thread interface to the values that
> are specified by the current standard for the C programming language.


I just went through both docs and tried to map pthread error codes to
corresponding C11-mandated error codes. Those that had no counterpart, I
just ignored, or bundled them all together under thrd_error as
appropriate. Do you propose a different strategy?

> 2.2 pthread_mutexattr_init/destroy


Yes that was the most hairy bit. This mechanism doesn't seem to map
exactly to what C11 wants. For instance the C standard talks about the
possibility of having a mtx_timed | mtx_recursive mutex, but as far as
I can tell with pthreads I can specify either PTHREAD_MUTEX_RECURSIVE or
PTHREAD_MUTEX_TIMED_NP (which is not even standard), but not both.


--
John Tsiombikas
http://nuclear.mutantstargoat.com/
 
Reply With Quote
 
Markus Elfring
Guest
Posts: n/a
 
      09-28-2012
> ... probably not, but it's not a matter of preference.
> Unless I'm much mistaken, the C11 standard dictates int as the type of
> the second argument of mtx_init (where all the mtx_ enumerations go),
> and as the return of all functions that need to indicate success
> or failure (thrd_ enumerations).


I suggest generally that a name is assigned to an enumeration. It might also be
a nice service if a "typedef" will be provided for each enumeration so that it
can become easier to reuse them as a data type in customised data structures.


> I just went through both docs and tried to map pthread error codes to
> corresponding C11-mandated error codes. Those that had no counterpart,
> I just ignored, or bundled them all together under thrd_error as
> appropriate. Do you propose a different strategy?


I guess that this implementation detail shows a software design challenge. I do
not like the ignorance of return values.


> Yes that was the most hairy bit. This mechanism doesn't seem to map
> exactly to what C11 wants. For instance the C standard talks about the
> possibility of having a mtx_timed | mtx_recursive mutex, but as far as
> I can tell with pthreads I can specify either PTHREAD_MUTEX_RECURSIVE or
> PTHREAD_MUTEX_TIMED_NP (which is not even standard), but not both.


Thanks that you pointed out such a portability issue.

I would like to point out once again that your function call
"pthread_mutexattr_init" shows the case of an unused return value. I would
prefer complete error detection and corresponding exception handling.

Some functions from the C standard API (like "mtx_destroy") have got the return
type "void". But the called Pthreads function provides an error code eventually.
How do you think about the reaction "abort()" in this use case?

Regards,
Markus
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      09-28-2012
Markus Elfring <> writes:
> John Tsiombikas <> writes:
>> ... probably not, but it's not a matter of preference.
>> Unless I'm much mistaken, the C11 standard dictates int as the type of
>> the second argument of mtx_init (where all the mtx_ enumerations go),
>> and as the return of all functions that need to indicate success
>> or failure (thrd_ enumerations).

>
> I suggest generally that a name is assigned to an enumeration. It
> might also be a nice service if a "typedef" will be provided for each
> enumeration so that it can become easier to reuse them as a data type
> in customised data structures.

[...]

The C standard doesn't provide typedefs for those enumerations.
An implementation that provided one would be intruding on the
user's namespace. And there's no particular reason for a typedef;
enumeration constants are of type int, not of the enumeration type.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      09-28-2012
On 09/28/2012 06:05 AM, Markus Elfring wrote:
>> ... probably not, but it's not a matter of preference.
>> Unless I'm much mistaken, the C11 standard dictates int as the type of
>> the second argument of mtx_init (where all the mtx_ enumerations go),
>> and as the return of all functions that need to indicate success
>> or failure (thrd_ enumerations).

>
> I suggest generally that a name is assigned to an enumeration. It might also be
> a nice service if a "typedef" will be provided for each enumeration so that it
> can become easier to reuse them as a data type in customised data structures.


He's trying to do the best that he can to implement a C99 substitute for
a new feature of C2011. C2011 does NOT specify a typedef name (or even
an enum tag) for the enumeration constants required to be declared in
<threads.h>. An implementation could provide a tag or a typedef or both,
but it can only use a reserved identifier for those purposes. If he used
a reserved identifier for that purpose, it would make his C99 code have
undefined behavior. If he used an identifier that was not reserved, his
substitute would be inappropriately infringing on the user's name space.

>> Yes that was the most hairy bit. This mechanism doesn't seem to map
>> exactly to what C11 wants. For instance the C standard talks about the
>> possibility of having a mtx_timed | mtx_recursive mutex, but as far as
>> I can tell with pthreads I can specify either PTHREAD_MUTEX_RECURSIVE or
>> PTHREAD_MUTEX_TIMED_NP (which is not even standard), but not both.

>
> Thanks that you pointed out such a portability issue.
>
> I would like to point out once again that your function call
> "pthread_mutexattr_init" shows the case of an unused return value. I would
> prefer complete error detection and corresponding exception handling.


I agree - mtx_init() should return thrd_error if
pthread_mutexattr_init() returns a non-zero value.

> Some functions from the C standard API (like "mtx_destroy") have got the return
> type "void". But the called Pthreads function provides an error code eventually.
> How do you think about the reaction "abort()" in this use case?


mtx_destroy() has, in itself, well-defined behavior that does not
include calling abort(). However, pthread_mutex_destroy() is only
allowed to fail if "The implementation has detected an attempt to
destroy the object referenced by mutex while it is locked or referenced
(for example, while being used in a pthread_cond_timedwait() or
pthread_cond_wait()) by another thread."

I haven't studied the C2011 threading specification carefully enough to
be certain, but I suspect that if C code using this wrapper library
could set up a situation in which pthread_mutex_destroy() would fail,
that code which does so might itself have undefined behavior, according
to C2011. If so, that would be sufficient to justify having
mtx_destroy() call abort().
--
James Kuyper
 
Reply With Quote
 
Jens Gustedt
Guest
Posts: n/a
 
      09-28-2012
Hello,

Am 27.09.2012 05:38, schrieb John Tsiombikas:
> Hello everyone! It's been a long time since I was last on usenet
>
> I was anxious to use the new standard C11 threading features, instead of
> platform-specific APIs, but unfortunately my system libc (GNU libc) does
> not implement that bit that yet.
> So, I wrote a trivial C11 thread wrapper over POSIX threads, and
> released it in the public domain just in case anyone is itching to use
> standard C threading in a new project just like me:
> https://github.com/jtsiomb/c11threads


There is a major flaw in your implementation that concerns the type of
the thread functions. You are simply casting C11 function type

int f(void*)

to the POSIX type

void* f(void*)

That is not only undefined behavior what is concerned C, but also
dangerous. The calling conventions for these type of functions may be
different on a given architecture, e.g returning the int value in a
reserved register and the void* on the stack.

Taking care of that incompatibility between C11 an POSIX threads needs
a bit more care than that, I think, if you want to be portable.

> The wrapper is so thin, I didn't think it made sense to make a proper
> library out of it, so it's just a header file with "static inline"
> functions. Drop it in your project, link with pthread and you're good to
> go.
>
> Disclaimer: I used a draft of the C11 standard while writting this code,
> since I don't actually have the final document. Feel free to notify me
> of any glaring discrepancies or omissions.


The xtime things are gone in the final version and all is now done
with the time structures as they existed before.

There is already an implementation of C11 threads as a wrapper around
POSIX threads that is publicly available. It is integrated in P99:

http://p99.gforge.inria.fr/

The C11 compatibility wrapper of P99 should be completely interface
compatible to C11 threads. (the include files are named differently,
though.)

Basically it also is a shallow wrapper using inline functions around
POSIX, but in addition P99 also offers
- an implementation/wrapper for the atomics
- of thread local variables
- _Generic (emulated through a macro)

if they are available (generally through gcc and friends)

Jens
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Reasonably priced C11 standard? Keith Thompson C Programming 85 04-06-2012 07:46 PM
Has Implicit Int been disabled in the new C11 standard? What aboutother previously depreciated constructions eg gets? Lord Voldermort C Programming 20 03-01-2012 10:57 AM
Comparing C11 compilers Quentin Pope C Programming 3 02-06-2012 09:36 PM
C11 reference book Ioannis Vranos C Programming 5 01-05-2012 12:01 AM
trivial or non-trivial object baibaichen C++ 3 01-12-2006 03:01 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57