mailing list of musl libc
 help / color / mirror / code / Atom feed
* C11 threads
@ 2014-07-25 10:00 Jens Gustedt
  2014-07-25 10:40 ` Szabolcs Nagy
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 10:00 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1555 bytes --]

Hi everybody,
 after I have seen that gcc since 4.9 has a working implementation of
atomics, I convinced myself to implement C11 threads within musl.

I was really amazed, in essence this was just work of several
hours. The cleanness of musl made it really a pleasant experience.

I think the implementation is straight forward, there are only very
few minor glitches possible. But I thought that I first discuss with
you.

Choices :

 - all types are just the corresponding POSIX types

Issues :

 - a lot of C11 are just weak symbols. to avoid polluting the link
   space of a C11 application, I had to transform a lot of POSIX
   function symbols into weak symbols, too.

 - the include file threads.h includes pthread.h, so the namespace of
   the C11 implementation is poluted with the pthreads stuff

 - pthread_create and thrd_create are still too tightly linked
   together. It would be good to split the corresponding file in two,
   but this would make maintenance a bit more difficult.

 - there are still some symbols missing, for some of the functions
   that I implemented as macro. work for a winter day

 - I don't have much tests for all of this


I join my version of the threads.h file that has some comments on the
minor choices.

Jens


-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::




[-- Attachment #2: threads.h --]
[-- Type: text/x-chdr, Size: 3757 bytes --]

#ifndef _THREADS_H
#define _THREADS_H

#include <pthread.h>
#include <errno.h>

enum {
  thrd_success = 0,
  thrd_busy = EBUSY,
  thrd_error = EINVAL,
  thrd_nomem = ENOMEM,
  thrd_timedout = ETIMEDOUT,
};

enum {
  mtx_plain = 0,
  mtx_recursive = PTHREAD_MUTEX_RECURSIVE,
  mtx_check = PTHREAD_MUTEX_ERRORCHECK,
  // all mutexes are timed, here. so this is a no-op
  mtx_timed = 0,
};

_Static_assert((mtx_plain | mtx_recursive | mtx_check | mtx_timed) == 3,
               "This implementation only works on top of musl");

#define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS

typedef pthread_cond_t cnd_t;
typedef pthread_mutex_t mtx_t;
typedef pthread_once_t once_flag;
typedef pthread_t thrd_t;
typedef pthread_key_t tss_t;

typedef int (*thrd_start_t)(void*);
typedef void (*tss_dtor_t)(void*);

#define thread_local _Thread_local

/* Don't create just additional symbols for the simple reason that the
   return type of the POSIX and C11 functions are different. */

int __pthread_once(once_flag *, void (*)(void));
// void call_once(once_flag *flag, void (*func)(void));
#define _call_once(FL, FU) (void)__pthread_once((FL), (FU))
#define call_once _call_once

_Noreturn void __pthread_exit(void *);
// _Noreturn void thrd_exit(int res);
#define _thrd_exit(RES) (__pthread_exit((void*)(intptr_t)(RES)))
#define thrd_exit _thrd_exit

int __pthread_cond_destroy(cnd_t *cond);
// void cnd_destroy(cnd_t *cond);
#define _cnd_destroy(CND) (void)__pthread_cond_destroy((CND))
#define cnd_destroy _cnd_destroy

void __pthread_mutex_destroy(mtx_t *mtx);
// void mtx_destroy(mtx_t *mtx);
#define _mtx_destroy(MTX) (void)__pthread_mutex_destroy((MTX))
#define mtx_destroy _mtx_destroy

int __pthread_mutex_unlock(mtx_t *mtx);
// int mtx_unlock(mtx_t *mtx);
#define _mtx_unlock(MTX) (__pthread_mutex_unlock((MTX)) ? thrd_error : thrd_success)
#define mtx_unlock _mtx_unlock

int __pthread_key_delete(tss_t key);
// void tss_delete(tss_t key);
#define _tss_delete(KEY)  (void)__pthread_key_delete((KEY))
#define tss_delete _tss_delete


/* Best of all worlds, these are just weak aliases */
int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast
int cnd_signal(cnd_t *);                      // pthread_cond_signal
int cnd_timedwait(cnd_t *restrict,            // pthread_cond_timedwait
                  mtx_t *restrict,
                  const struct timespec *restrict);
int cnd_wait(cnd_t *cond, mtx_t *mtx);        // pthread_cond_wait

int mtx_lock(mtx_t *);                        // pthread_mutex_lock
int mtx_timedlock(mtx_t *restrict,            // pthread_mutex_timedlock
                  const struct timespec *restrict);
int mtx_trylock(mtx_t *);                     // pthread_mutex_trylock

thrd_t thrd_current(void);                    // pthread_self
int thrd_equal(thrd_t, thrd_t);               // pthread_equal
int thrd_detach(thrd_t);                      // pthread_detach

int tss_create(tss_t *, tss_dtor_t);          // pthread_key_create
void *tss_get(tss_t);                         // pthread_getspecific
int tss_set(tss_t, void *);                   // pthread_setspecific


/* specialized implementations */

int cnd_init(cnd_t *);
int mtx_init(mtx_t *, int);

// reimplemented because of different calling convention
// shaves of a lot of code for attributes and cancelation
int thrd_create(thrd_t *,
                thrd_start_t,
                void *);

// reimplemented because of different calling convention
int thrd_join(thrd_t, int *);

// reimplemented because of different return value convention
int thrd_sleep(const struct timespec *,
               struct timespec *);

// reimplemented because of different return type
void thrd_yield(void);

#endif

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 10:00 C11 threads Jens Gustedt
@ 2014-07-25 10:40 ` Szabolcs Nagy
  2014-07-25 11:06   ` Jens Gustedt
  0 siblings, 1 reply; 21+ messages in thread
From: Szabolcs Nagy @ 2014-07-25 10:40 UTC (permalink / raw)
  To: Jens Gustedt; +Cc: musl

* Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
>  after I have seen that gcc since 4.9 has a working implementation of
> atomics, I convinced myself to implement C11 threads within musl.
> 

the conclusion about threads.h was that it should be
abi compatible with glibc so we are waiting for them

so i think you should coordinate with libc-alpha too

> Choices :
> 
>  - all types are just the corresponding POSIX types
> 

if glibc does the same then it's ok

> Issues :
> 
>  - a lot of C11 are just weak symbols. to avoid polluting the link
>    space of a C11 application, I had to transform a lot of POSIX
>    function symbols into weak symbols, too.
> 

i think this not ok: posix usually requires inequal
function pointers for all public functions

>  - the include file threads.h includes pthread.h, so the namespace of
>    the C11 implementation is poluted with the pthreads stuff
> 

i think this is not ok in the final version

>  - pthread_create and thrd_create are still too tightly linked
>    together. It would be good to split the corresponding file in two,
>    but this would make maintenance a bit more difficult.
> 
>  - there are still some symbols missing, for some of the functions
>    that I implemented as macro. work for a winter day
> 

i assume you just have to add a ptototype before the macro
definition and provide a trivial wrapper implementation

>  - I don't have much tests for all of this

> 
> /* Don't create just additional symbols for the simple reason that the
>    return type of the POSIX and C11 functions are different. */
> 
> int __pthread_once(once_flag *, void (*)(void));
> // void call_once(once_flag *flag, void (*func)(void));
> #define _call_once(FL, FU) (void)__pthread_once((FL), (FU))
> #define call_once _call_once
> 

the additional symbols are necessary

and _[a-z] is not reserved for arbitrary usage for
the implementation (only for file scope identifiers)


> /* Best of all worlds, these are just weak aliases */
> int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast

posix is not yet aligned with c11, but i think they will
require inequal function pointers for these functions


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 10:40 ` Szabolcs Nagy
@ 2014-07-25 11:06   ` Jens Gustedt
  2014-07-25 13:04     ` Szabolcs Nagy
  2014-07-25 15:41     ` Rich Felker
  0 siblings, 2 replies; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 11:06 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 3789 bytes --]

Hi,
thanks a lot for your feedback.

Am Freitag, den 25.07.2014, 12:40 +0200 schrieb Szabolcs Nagy:
> * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
> >  after I have seen that gcc since 4.9 has a working implementation of
> > atomics, I convinced myself to implement C11 threads within musl.
> > 
> 
> the conclusion about threads.h was that it should be
> abi compatible with glibc so we are waiting for them

They have that has a student summer project, so it seems to have low
priority for them.

> so i think you should coordinate with libc-alpha too
> 
> > Choices :
> > 
> >  - all types are just the corresponding POSIX types
> > 
> 
> if glibc does the same then it's ok

At least from the project description it seems that they prospect an
incremental implementation.

> > Issues :
> > 
> >  - a lot of C11 are just weak symbols. to avoid polluting the link
> >    space of a C11 application, I had to transform a lot of POSIX
> >    function symbols into weak symbols, too.
> > 

> i think this not ok: posix usually requires inequal
> function pointers for all public functions

C11 requires that the namespace not be polluted.

That conflict could be solved conveniently and easily by

 (1) compiling the same files twice and replacing the pthread symbol
     by the other in the second compilation

 (2) copy the .o file and to some ld magic

Which one to choose?

> >  - the include file threads.h includes pthread.h, so the namespace of
> >    the C11 implementation is poluted with the pthreads stuff
> > 
> 
> i think this is not ok in the final version

yes, I thought so, too. I would have to find a convenient way to just
include the magic constants. Or would it be ok, to just duplicate
them.

For the types this should be easy to have them typedef'ed to some
opaque struct.

> >  - pthread_create and thrd_create are still too tightly linked
> >    together. It would be good to split the corresponding file in two,
> >    but this would make maintenance a bit more difficult.
> > 
> >  - there are still some symbols missing, for some of the functions
> >    that I implemented as macro. work for a winter day
> > 
> 
> i assume you just have to add a ptototype before the macro
> definition and provide a trivial wrapper implementation

yes, was my thought, too.

> >  - I don't have much tests for all of this
> 
> > 
> > /* Don't create just additional symbols for the simple reason that the
> >    return type of the POSIX and C11 functions are different. */
> > 
> > int __pthread_once(once_flag *, void (*)(void));
> > // void call_once(once_flag *flag, void (*func)(void));
> > #define _call_once(FL, FU) (void)__pthread_once((FL), (FU))
> > #define call_once _call_once
> > 
> 
> the additional symbols are necessary
> 
> and _[a-z] is not reserved for arbitrary usage for
> the implementation (only for file scope identifiers)

Yes, I know, just was a temporary hack to get things going.

> > /* Best of all worlds, these are just weak aliases */
> > int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast
> 
> posix is not yet aligned with c11, but i think they will
> require inequal function pointers for these functions

The term "inequal function pointer" had nothing pop up. Could you give
a reference to the relevant part in POSIX that makes the requirement
for a "strong" symbol?

Thanks

Jens


-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::




[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 11:06   ` Jens Gustedt
@ 2014-07-25 13:04     ` Szabolcs Nagy
  2014-07-25 13:38       ` Jens Gustedt
                         ` (2 more replies)
  2014-07-25 15:41     ` Rich Felker
  1 sibling, 3 replies; 21+ messages in thread
From: Szabolcs Nagy @ 2014-07-25 13:04 UTC (permalink / raw)
  To: musl

* Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 13:06:44 +0200]:
> Am Freitag, den 25.07.2014, 12:40 +0200 schrieb Szabolcs Nagy:
> > * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
> > > /* Best of all worlds, these are just weak aliases */
> > > int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast
> > 
> > posix is not yet aligned with c11, but i think they will
> > require inequal function pointers for these functions
> 
> The term "inequal function pointer" had nothing pop up. Could you give
> a reference to the relevant part in POSIX that makes the requirement
> for a "strong" symbol?


hm i might be wrong:

there is a requirement in c and posix that the address of a
standard function can be taken and that == is only true for
function pointers if they point to the same function

but i don't see any requirement that each library function
must be distinct

and there is a dr that implies the opposite:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_078.html

without explanation the response says h can return 0.

the musl math library currently defines distinct long double
functions even if long double and double have the same
representation, they could be weak aliases if the standard
allows this..


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 13:04     ` Szabolcs Nagy
@ 2014-07-25 13:38       ` Jens Gustedt
  2014-07-25 13:42       ` Morten Welinder
  2014-07-25 16:14       ` Rich Felker
  2 siblings, 0 replies; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 13:38 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1534 bytes --]

Am Freitag, den 25.07.2014, 15:04 +0200 schrieb Szabolcs Nagy:
> > The term "inequal function pointer" had nothing pop up. Could you give
> > a reference to the relevant part in POSIX that makes the requirement
> > for a "strong" symbol?
> 
> 
> hm i might be wrong:
> 
> there is a requirement in c and posix that the address of a
> standard function can be taken and that == is only true for
> function pointers if they point to the same function
> 
> but i don't see any requirement that each library function
> must be distinct
> 
> and there is a dr that implies the opposite:
> 
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_078.html
> 
> without explanation the response says h can return 0.

That DR is only for C. Would be interesting to have something for
POSIX, too.

> the musl math library currently defines distinct long double
> functions even if long double and double have the same
> representation, they could be weak aliases if the standard
> allows this..

It is completely sound as a policy to have no exported user functions
as weak aliases. It reduces the possibility the user shooting him or
herself in the foot.

Whatever choice would be fine with me.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::




[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 13:04     ` Szabolcs Nagy
  2014-07-25 13:38       ` Jens Gustedt
@ 2014-07-25 13:42       ` Morten Welinder
  2014-07-25 14:15         ` Szabolcs Nagy
  2014-07-25 16:14       ` Rich Felker
  2 siblings, 1 reply; 21+ messages in thread
From: Morten Welinder @ 2014-07-25 13:42 UTC (permalink / raw)
  To: musl

> the musl math library currently defines distinct long double [...]

You cannot compare a "double" function pointer to a "long double"
function pointer.  The types are incompatible, even if they have the
same representation.

Hence I don't believe a C program can even tell if they are the same.

M.





On Fri, Jul 25, 2014 at 9:04 AM, Szabolcs Nagy <nsz@port70.net> wrote:
> * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 13:06:44 +0200]:
>> Am Freitag, den 25.07.2014, 12:40 +0200 schrieb Szabolcs Nagy:
>> > * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
>> > > /* Best of all worlds, these are just weak aliases */
>> > > int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast
>> >
>> > posix is not yet aligned with c11, but i think they will
>> > require inequal function pointers for these functions
>>
>> The term "inequal function pointer" had nothing pop up. Could you give
>> a reference to the relevant part in POSIX that makes the requirement
>> for a "strong" symbol?
>
>
> hm i might be wrong:
>
> there is a requirement in c and posix that the address of a
> standard function can be taken and that == is only true for
> function pointers if they point to the same function
>
> but i don't see any requirement that each library function
> must be distinct
>
> and there is a dr that implies the opposite:
>
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_078.html
>
> without explanation the response says h can return 0.
>
> the musl math library currently defines distinct long double
> functions even if long double and double have the same
> representation, they could be weak aliases if the standard
> allows this..


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 13:42       ` Morten Welinder
@ 2014-07-25 14:15         ` Szabolcs Nagy
  0 siblings, 0 replies; 21+ messages in thread
From: Szabolcs Nagy @ 2014-07-25 14:15 UTC (permalink / raw)
  To: musl

* Morten Welinder <mwelinder@gmail.com> [2014-07-25 09:42:52 -0400]:
> > the musl math library currently defines distinct long double [...]
> 
> You cannot compare a "double" function pointer to a "long double"
> function pointer.  The types are incompatible, even if they have the
> same representation.
> 
> Hence I don't believe a C program can even tell if they are the same.
> 

conversion between incompatible function pointers is allowed

and i think == should work on converted pointers too:

void f(void) {}
void g(int x) {}
int h() {return f == (void(*)(void))g;}




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 11:06   ` Jens Gustedt
  2014-07-25 13:04     ` Szabolcs Nagy
@ 2014-07-25 15:41     ` Rich Felker
  2014-07-25 17:10       ` Jens Gustedt
  1 sibling, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-25 15:41 UTC (permalink / raw)
  To: musl

On Fri, Jul 25, 2014 at 01:06:44PM +0200, Jens Gustedt wrote:
> Hi,
> thanks a lot for your feedback.
> 
> Am Freitag, den 25.07.2014, 12:40 +0200 schrieb Szabolcs Nagy:
> > * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
> > >  after I have seen that gcc since 4.9 has a working implementation of
> > > atomics, I convinced myself to implement C11 threads within musl.
> > > 
> > 
> > the conclusion about threads.h was that it should be
> > abi compatible with glibc so we are waiting for them
> 
> They have that has a student summer project, so it seems to have low
> priority for them.

Their GSOC funding for the project fell through due to missed
deadlines, so it's now an unfunded student project if it's even moving
forward at all. That may be the reason. :(

> > so i think you should coordinate with libc-alpha too
> > 
> > > Choices :
> > > 
> > >  - all types are just the corresponding POSIX types
> > > 
> > 
> > if glibc does the same then it's ok
> 
> At least from the project description it seems that they prospect an
> incremental implementation.

Yes, that was their decision and they were generally uninterested in
discussing whether it was the best decision. I tend to agree that it's
the right choice, but thought it could use more discussion before a
decision was made.

> > > Issues :
> > > 
> > >  - a lot of C11 are just weak symbols. to avoid polluting the link
> > >    space of a C11 application, I had to transform a lot of POSIX
> > >    function symbols into weak symbols, too.
> > > 
> 
> > i think this not ok: posix usually requires inequal
> > function pointers for all public functions
> 
> C11 requires that the namespace not be polluted.
> 
> That conflict could be solved conveniently and easily by
> 
>  (1) compiling the same files twice and replacing the pthread symbol
>      by the other in the second compilation
> 
>  (2) copy the .o file and to some ld magic
> 
> Which one to choose?

Neither of these is very reasonable. Probably the best is to
namespace-protect (i.e. prefix with __ and add the external name as a
weak alias) all of the pthread functions which need to be used for
implementing C11 functions, then add either second weak aliases (if
the equal function pointer issue is not a problem and the signature is
identical) or thin wrappers (probably my preference anyway) for the
C11 functions to call the __pthread ones.

The latter also allows us to add alternative implementations for the
C11 ones later on an incremental basis, if we want to. I generally
don't like the whole C11 threads mess, but the one potential advantage
they have is having weaker semantics which may allow better
performance, and definitely allows smaller size if the application
only uses them (but of course makes libc.a and libc.so larger).

The other thing nice about eventually having mostly-separate (I say
mostly because thread creation/destruction still needs to be unified,
I would think) code for POSIX and C11 would be that we could avoid
having permanent restrictions on the namespace usage for pthread
functions.

> > >  - the include file threads.h includes pthread.h, so the namespace of
> > >    the C11 implementation is poluted with the pthreads stuff
> > > 
> > 
> > i think this is not ok in the final version
> 
> yes, I thought so, too. I would have to find a convenient way to just
> include the magic constants. Or would it be ok, to just duplicate
> them.
> 
> For the types this should be easy to have them typedef'ed to some
> opaque struct.

For the types that vary per-arch, I don't see any way around having
them in the alltypes.h.in bits. As for the constants, which ones are
you talking about? I don't think it's so easy to directly use the
POSIX ones for C11 since they have some different semantics (flag bits
vs enumeration-style) for a few. Also this is one area where we still
need to be careful to match the glibc ABI.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 13:04     ` Szabolcs Nagy
  2014-07-25 13:38       ` Jens Gustedt
  2014-07-25 13:42       ` Morten Welinder
@ 2014-07-25 16:14       ` Rich Felker
  2014-07-25 21:59         ` Jens Gustedt
  2 siblings, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-25 16:14 UTC (permalink / raw)
  To: musl

On Fri, Jul 25, 2014 at 03:04:39PM +0200, Szabolcs Nagy wrote:
> > The term "inequal function pointer" had nothing pop up. Could you give
> > a reference to the relevant part in POSIX that makes the requirement
> > for a "strong" symbol?
> 
> 
> hm i might be wrong:
> 
> there is a requirement in c and posix that the address of a
> standard function can be taken and that == is only true for
> function pointers if they point to the same function
> 
> but i don't see any requirement that each library function
> must be distinct
> 
> and there is a dr that implies the opposite:
> 
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_078.html
> 
> without explanation the response says h can return 0.

Indeed there is no explanation. I don't think it could be related to
macros because my understanding is that only function-like macros are
allowed for the standard functions, i.e. you can override such macros
by using ().

Both C99 and C11 contain in 7.1.4 paragraph 1 a footnote (161 or 185,
respectively) reading:

"This means that an implementation shall provide an actual function
for each library function, even if it also provides a macro for that
function."

This suggests to me that there should be a one-to-one correspondence
between actual functions and library functions, but maybe I'm reading
too much into it.

> the musl math library currently defines distinct long double
> functions even if long double and double have the same
> representation, they could be weak aliases if the standard
> allows this..

Indeed. If this issue is resolved to allow it, I think we should make
this change and remove some otherwise-useless bloat.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 15:41     ` Rich Felker
@ 2014-07-25 17:10       ` Jens Gustedt
  2014-07-25 22:19         ` Rich Felker
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 17:10 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 6091 bytes --]

Hello,

Am Freitag, den 25.07.2014, 11:41 -0400 schrieb Rich Felker:
> On Fri, Jul 25, 2014 at 01:06:44PM +0200, Jens Gustedt wrote:
> > Hi,
> > thanks a lot for your feedback.
> > 
> > Am Freitag, den 25.07.2014, 12:40 +0200 schrieb Szabolcs Nagy:
> > > * Jens Gustedt <jens.gustedt@inria.fr> [2014-07-25 12:00:37 +0200]:
> > > >  after I have seen that gcc since 4.9 has a working implementation of
> > > > atomics, I convinced myself to implement C11 threads within musl.
> > > > 
> > > 
> > > the conclusion about threads.h was that it should be
> > > abi compatible with glibc so we are waiting for them
> > 
> > They have that has a student summer project, so it seems to have low
> > priority for them.
> 
> Their GSOC funding for the project fell through due to missed
> deadlines, so it's now an unfunded student project if it's even moving
> forward at all. That may be the reason. :(
> 
> > > so i think you should coordinate with libc-alpha too
> > > 
> > > > Choices :
> > > > 
> > > >  - all types are just the corresponding POSIX types
> > > > 
> > > 
> > > if glibc does the same then it's ok
> > 
> > At least from the project description it seems that they prospect an
> > incremental implementation.
> 
> Yes, that was their decision and they were generally uninterested in
> discussing whether it was the best decision. I tend to agree that it's
> the right choice, but thought it could use more discussion before a
> decision was made.

Ideally, yes. For the time being we can mark this feature as
"experimental", I could even maintain this separately, if you
want. But honestly I don't expect much reaction from anywhere.

> > > > Issues :
> > > > 
> > > >  - a lot of C11 are just weak symbols. to avoid polluting the link
> > > >    space of a C11 application, I had to transform a lot of POSIX
> > > >    function symbols into weak symbols, too.
> > > > 
> > 
> > > i think this not ok: posix usually requires inequal
> > > function pointers for all public functions
> > 
> > C11 requires that the namespace not be polluted.
> > 
> > That conflict could be solved conveniently and easily by
> > 
> >  (1) compiling the same files twice and replacing the pthread symbol
> >      by the other in the second compilation
> > 
> >  (2) copy the .o file and to some ld magic
> > 
> > Which one to choose?
> 
> Neither of these is very reasonable. Probably the best is to
> namespace-protect (i.e. prefix with __ and add the external name as a
> weak alias) all of the pthread functions which need to be used for
> implementing C11 functions, then add either second weak aliases (if
> the equal function pointer issue is not a problem and the signature is
> identical) or thin wrappers (probably my preference anyway) for the
> C11 functions to call the __pthread ones.

Basically what I had from the start is the variant with two sets of
weak aliases.

> The latter also allows us to add alternative implementations for the
> C11 ones later on an incremental basis, if we want to.

I don't think that the weak alias approach inhibits this in any way.

> I generally
> don't like the whole C11 threads mess, but the one potential advantage
> they have is having weaker semantics which may allow better
> performance,

The weaker semantic is effectively too weak, and there are ongoing
efforts to amend that.

The advantages that I see that this doesn't need all that attr stuff
and has no concept of cancellation.

> and definitely allows smaller size if the application
> only uses them (but of course makes libc.a and libc.so larger).

If we use weak aliases, this basically blows up the symbol table a
bit.

When I strip my test executable, it is impressively small.

> The other thing nice about eventually having mostly-separate (I say
> mostly because thread creation/destruction still needs to be unified,
> I would think) code for POSIX and C11 would be that we could avoid
> having permanent restrictions on the namespace usage for pthread
> functions.
> 
> > > >  - the include file threads.h includes pthread.h, so the namespace of
> > > >    the C11 implementation is poluted with the pthreads stuff
> > > > 
> > > 
> > > i think this is not ok in the final version
> > 
> > yes, I thought so, too. I would have to find a convenient way to just
> > include the magic constants. Or would it be ok, to just duplicate
> > them.
> > 
> > For the types this should be easy to have them typedef'ed to some
> > opaque struct.
> 
> For the types that vary per-arch, I don't see any way around having
> them in the alltypes.h.in bits.

The only types that seem to be in bits are mutex and condition. All
others seem to be arch independent.

On the long we should probably have __pthread names in the alltypes.h
files and typedef these in pthread.h and threads.h respectively.

> As for the constants, which ones are
> you talking about?

the mtx_ constants are the critical ones.

thrd_error and friends can easily be mapped to EXXX error codes from
errno.h. Since these names are all reserved anyway, including errno.h
shouldn't do much harm.

> I don't think it's so easy to directly use the
> POSIX ones for C11 since they have some different semantics (flag bits
> vs enumeration-style) for a few.

the mtx_ ones are basically flags, just as the PTHREAD_MUTEX_ ones.
This fits well with the actual values of these in musl.

And then there is TSS_DTOR_ITERATIONS versus
PTHREAD_DESTRUCTOR_ITERATIONS, not a big deal. We just have to agree
on something.

> Also this is one area where we still
> need to be careful to match the glibc ABI.

Sure. In particular we shouldn't change any existing ABI.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::





[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 16:14       ` Rich Felker
@ 2014-07-25 21:59         ` Jens Gustedt
  2014-07-25 22:25           ` Rich Felker
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 21:59 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 2576 bytes --]

Am Freitag, den 25.07.2014, 12:14 -0400 schrieb Rich Felker:
> On Fri, Jul 25, 2014 at 03:04:39PM +0200, Szabolcs Nagy wrote:
> > http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_078.html
> > 
> > without explanation the response says h can return 0.
> 
> Indeed there is no explanation. I don't think it could be related to
> macros because my understanding is that only function-like macros are
> allowed for the standard functions, i.e. you can override such macros
> by using ().

Indeed, I don't think that it has to do with macros per se, but with
the fact that one function can replace another one if the
implementation has the information that all requirements are
fulfilled. Indeed, if you have a version of memcpy that can cope with
overlapping memory blocks, you may also use it as memove.

> Both C99 and C11 contain in 7.1.4 paragraph 1 a footnote (161 or 185,
> respectively) reading:
> 
> "This means that an implementation shall provide an actual function
> for each library function, even if it also provides a macro for that
> function."
> 
> This suggests to me that there should be a one-to-one correspondence
> between actual functions and library functions, but maybe I'm reading
> too much into it.

I don't see where you get the one-to-one. For me this only says that
any library "function" can be used through the pointer-to-function.

I think the only intention is that any library function can be taken
as pointer, that pointer can be stored somewhere and then the
underlying function can be called from any context.

> > the musl math library currently defines distinct long double
> > functions even if long double and double have the same
> > representation, they could be weak aliases if the standard
> > allows this..
> 
> Indeed. If this issue is resolved to allow it, I think we should make
> this change and remove some otherwise-useless bloat.

If you are thinking in that direction, we definitively shouldn't use
trivial wrapper functions for the C11 functions. In all cases where
there is a trivial shift in the interface (such as the void return) I
would stay with the macro, and provide the additional symbol only for
the rare cases that someone asks for the address.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::





[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 17:10       ` Jens Gustedt
@ 2014-07-25 22:19         ` Rich Felker
  2014-07-25 23:26           ` Jens Gustedt
  0 siblings, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-25 22:19 UTC (permalink / raw)
  To: musl

On Fri, Jul 25, 2014 at 07:10:02PM +0200, Jens Gustedt wrote:
> > > > if glibc does the same then it's ok
> > > 
> > > At least from the project description it seems that they prospect an
> > > incremental implementation.
> > 
> > Yes, that was their decision and they were generally uninterested in
> > discussing whether it was the best decision. I tend to agree that it's
> > the right choice, but thought it could use more discussion before a
> > decision was made.
> 
> Ideally, yes. For the time being we can mark this feature as
> "experimental", I could even maintain this separately, if you
> want. But honestly I don't expect much reaction from anywhere.

Since glibc is going that way, I think we should keep the type sizes
the same but leave it explicitly undefined to mix calls to C11 and
POSIX functions on the same synchronization objects.

> > > C11 requires that the namespace not be polluted.
> > > 
> > > That conflict could be solved conveniently and easily by
> > > 
> > >  (1) compiling the same files twice and replacing the pthread symbol
> > >      by the other in the second compilation
> > > 
> > >  (2) copy the .o file and to some ld magic
> > > 
> > > Which one to choose?
> > 
> > Neither of these is very reasonable. Probably the best is to
> > namespace-protect (i.e. prefix with __ and add the external name as a
> > weak alias) all of the pthread functions which need to be used for
> > implementing C11 functions, then add either second weak aliases (if
> > the equal function pointer issue is not a problem and the signature is
> > identical) or thin wrappers (probably my preference anyway) for the
> > C11 functions to call the __pthread ones.
> 
> Basically what I had from the start is the variant with two sets of
> weak aliases.

OK. I didn't see that in your first email but perhaps I read it wrong.

> > The latter also allows us to add alternative implementations for the
> > C11 ones later on an incremental basis, if we want to.
> 
> I don't think that the weak alias approach inhibits this in any way.

It doesn't; I just meant that having the separate file/function
already in place makes the change smaller if we add an independent
implementation. But I agree it's a small difference and probably was
pointless to mention.

> > I generally
> > don't like the whole C11 threads mess, but the one potential advantage
> > they have is having weaker semantics which may allow better
> > performance,
> 
> The weaker semantic is effectively too weak, and there are ongoing
> efforts to amend that.

Could you elaborate? Perhaps we're thinking of different things.

One aspect is that all POSIX synchronization functions are full
barriers, whereas presumably the C11 ones are proper acquire/release
barriers as appropriate for the operation being performed.

Another is Austin Group issue #755, which I'm hoping the WG14 will not
rule the same way on. The Austin Group's resolution for POSIX mutexes
makes recursive and error-checking mutexes very expensive and requires
threads to maintain a record of all such mutexes they own. I have not
yet implemented this in musl but I plan to do so soon (BTW this needs
to be added to the roadmap).

> The advantages that I see that this doesn't need all that attr stuff
> and has no concept of cancellation.

Cancellation is rather irrelevant to the synchronization primitives.
Obviously C11's lack of cancellation makes C11 threads much easier to
implement if you're not also doing POSIX threads, but if you're doing
both, the fact that C11 lacks a cancellation function makes almost no
difference (just one simple cleanup function in condvar wait).

> > and definitely allows smaller size if the application
> > only uses them (but of course makes libc.a and libc.so larger).
> 
> If we use weak aliases, this basically blows up the symbol table a
> bit.
> 
> When I strip my test executable, it is impressively small.

Yes, this is one reason I don't want __-prefixed symbols for
everything, just functions that really _need_ namespace-safe versions.
We should probably do some linking tests against all the C11 functions
to make sure they're not pulling in functions outside the C11
namespace and add __-prefixed versions of those functions only, rather
than preemptively trying to guess what needs protection.

> > > For the types this should be easy to have them typedef'ed to some
> > > opaque struct.
> > 
> > For the types that vary per-arch, I don't see any way around having
> > them in the alltypes.h.in bits.
> 
> The only types that seem to be in bits are mutex and condition. All
> others seem to be arch independent.

Ah yes the others are probably not needed for C11.

> On the long we should probably have __pthread names in the alltypes.h
> files and typedef these in pthread.h and threads.h respectively.

That doesn't work because both sys/types.h and pthread.h have to
expose the pthread names.

> > As for the constants, which ones are
> > you talking about?
> 
> the mtx_ constants are the critical ones.
> 
> thrd_error and friends can easily be mapped to EXXX error codes from
> errno.h. Since these names are all reserved anyway, including errno.h
> shouldn't do much harm.

I don't think including errno.h implicitly is permitted. E* is only
reserved when errno.h is included. Anyway this is somewhere we wasnt
to agree with glibc on the values; I suspect they'll just use values
1,2,... rather than errno codes. If so, that means we really need a
wrapper function rather than just an alias.

> > I don't think it's so easy to directly use the
> > POSIX ones for C11 since they have some different semantics (flag bits
> > vs enumeration-style) for a few.
> 
> the mtx_ ones are basically flags, just as the PTHREAD_MUTEX_ ones.
> This fits well with the actual values of these in musl.

The PTHREAD_MUTEX_* ones are not flags; each corresponds to a single
type and they are not combinable. The C11 ones are combinable, but
mtx_timed is useless -- there's no need to care whether it will be
used for timed operations when it's initialized.

BTW n1570 only has 4 possible values to pass to mtx_init, but reads
(7.26.4.2 p2):

"The mtx_init function creates a mutex object with properties
indicated by type, which must have one of the six values:"

Any idea if six is just a mistake or if there are some values missing
from the list?

> And then there is TSS_DTOR_ITERATIONS versus
> PTHREAD_DESTRUCTOR_ITERATIONS, not a big deal. We just have to agree
> on something.
> 
> > Also this is one area where we still
> > need to be careful to match the glibc ABI.
> 
> Sure. In particular we shouldn't change any existing ABI.

Beyond not changing any existing ABI, I want to aim for making any new
ABIs added compatible.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 21:59         ` Jens Gustedt
@ 2014-07-25 22:25           ` Rich Felker
  0 siblings, 0 replies; 21+ messages in thread
From: Rich Felker @ 2014-07-25 22:25 UTC (permalink / raw)
  To: musl

On Fri, Jul 25, 2014 at 11:59:06PM +0200, Jens Gustedt wrote:
> > > the musl math library currently defines distinct long double
> > > functions even if long double and double have the same
> > > representation, they could be weak aliases if the standard
> > > allows this..
> > 
> > Indeed. If this issue is resolved to allow it, I think we should make
> > this change and remove some otherwise-useless bloat.
> 
> If you are thinking in that direction, we definitively shouldn't use
> trivial wrapper functions for the C11 functions. In all cases where
> there is a trivial shift in the interface (such as the void return) I
> would stay with the macro, and provide the additional symbol only for
> the rare cases that someone asks for the address.

I don't want macros expanding to __-prefixed pthread names. This leaks
implementation internals into the ABI of binaries linked to musl and
makes it difficult or impossible to change those internals. glibc made
this choice in a lot of places (e.g. __strtol_internal, __ctype*, ...)
and it's one of the things that I (and many of our community members)
don't like about glibc.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 22:19         ` Rich Felker
@ 2014-07-25 23:26           ` Jens Gustedt
  2014-07-26  2:24             ` Rich Felker
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 23:26 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 6749 bytes --]

Am Freitag, den 25.07.2014, 18:19 -0400 schrieb Rich Felker:
> Since glibc is going that way, I think we should keep the type sizes
> the same but leave it explicitly undefined to mix calls to C11 and
> POSIX functions on the same synchronization objects.

yes, defitively. Not even for the synchronization functions, basically
none from pthread and C11 thread should be mixed, I think. I thought
of figuring out a way to make this even a link error.

> Could you elaborate? Perhaps we're thinking of different things.

probably.

The C11 specification is so bad, that some of the functions don't even
have a semantic description of what they are supposed to achieve. E.g
tss_t completely lacks a description of what a destructor is, what
the "iterations" in TSS_DTOR_ITERATIONS describe etc. Parts of it are
or will be adressed TC, but there is much more. I wrote my findings up
here

http://gustedt.wordpress.com/2012/10/14/c11-defects-c-threads-are-not-realizable-with-posix-threads/

> One aspect is that all POSIX synchronization functions are full
> barriers, whereas presumably the C11 ones are proper acquire/release
> barriers as appropriate for the operation being performed.

That is probably the intention. But e.g mtx_lock is only required to
synchronize with calls to mtx_unlock, not with other calls to mtx_lock
or similar. The term "lock" isn't even defined.

> Another is Austin Group issue #755, which I'm hoping the WG14 will not
> rule the same way on. The Austin Group's resolution for POSIX mutexes
> makes recursive and error-checking mutexes very expensive and requires
> threads to maintain a record of all such mutexes they own. I have not
> yet implemented this in musl but I plan to do so soon (BTW this needs
> to be added to the roadmap).

I am not sure that I completely understand what this is about. But in
any case, C threads don't have error checking :)

> > The advantages that I see that this doesn't need all that attr stuff
> > and has no concept of cancellation.
> 
> Cancellation is rather irrelevant to the synchronization primitives.
> Obviously C11's lack of cancellation makes C11 threads much easier to
> implement if you're not also doing POSIX threads, but if you're doing
> both, the fact that C11 lacks a cancellation function makes almost no
> difference (just one simple cleanup function in condvar wait).

There is a bit more, maybe. __timedwait does cleanup push and pop and
messes around with cancelbuf. (But probably I just don't understand
enough what's going on, here.)

In any case, without attributes and possible cancelation, thrd_create
becomes significantly shorter than pthread_create.

And to my limited experience having well defined atomics that are
integrated in the language, often helps to completely avoid mutexes
and conditions.

> > > and definitely allows smaller size if the application
> > > only uses them (but of course makes libc.a and libc.so larger).
> > 
> > If we use weak aliases, this basically blows up the symbol table a
> > bit.
> > 
> > When I strip my test executable, it is impressively small.
> 
> Yes, this is one reason I don't want __-prefixed symbols for
> everything, just functions that really _need_ namespace-safe versions.
> We should probably do some linking tests against all the C11 functions
> to make sure they're not pulling in functions outside the C11
> namespace and add __-prefixed versions of those functions only, rather
> than preemptively trying to guess what needs protection.

I tried to do that already.

> > > > For the types this should be easy to have them typedef'ed to some
> > > > opaque struct.
> > > 
> > > For the types that vary per-arch, I don't see any way around having
> > > them in the alltypes.h.in bits.
> > 
> > The only types that seem to be in bits are mutex and condition. All
> > others seem to be arch independent.
> 
> Ah yes the others are probably not needed for C11.
> 
> > On the long we should probably have __pthread names in the alltypes.h
> > files and typedef these in pthread.h and threads.h respectively.
> 
> That doesn't work because both sys/types.h and pthread.h have to
> expose the pthread names.
> 
> > > As for the constants, which ones are
> > > you talking about?
> > 
> > the mtx_ constants are the critical ones.
> > 
> > thrd_error and friends can easily be mapped to EXXX error codes from
> > errno.h. Since these names are all reserved anyway, including errno.h
> > shouldn't do much harm.
> 
> I don't think including errno.h implicitly is permitted. E* is only
> reserved when errno.h is included. Anyway this is somewhere we wasnt
> to agree with glibc on the values; I suspect they'll just use values
> 1,2,... rather than errno codes. If so, that means we really need a
> wrapper function rather than just an alias.

Hm, not sure that I follow.

I only need EBUSY, EINVAL, ENOMEM, and ETIMEDOUT, and effectively only
that these are consistent with the rest of the C library, which for
this implementation of C threads will always be musl.

> > > I don't think it's so easy to directly use the
> > > POSIX ones for C11 since they have some different semantics (flag bits
> > > vs enumeration-style) for a few.
> > 
> > the mtx_ ones are basically flags, just as the PTHREAD_MUTEX_ ones.
> > This fits well with the actual values of these in musl.
> 
> The PTHREAD_MUTEX_* ones are not flags; each corresponds to a single
> type and they are not combinable.

ah, ok, anyhow the only one that I am really interested in is
PTHREAD_MUTEX_RECURSIVE. So perhaps I can push that down to the
implementation.

> The C11 ones are combinable, but mtx_timed is useless

yes, I think I already noted that in the file that I attached to my
initial mail

> -- there's no need to care whether it will be
> used for timed operations when it's initialized.
> 
> BTW n1570 only has 4 possible values to pass to mtx_init, but reads
> (7.26.4.2 p2):
> 
> "The mtx_init function creates a mutex object with properties
> indicated by type, which must have one of the six values:"
> 
> Any idea if six is just a mistake or if there are some values missing
> from the list?

It is just a leftover, and has/willbe been corrected.

To summarize, I'd need to get

EBUSY, EINVAL, ENOMEM, ETIMEDOUT and TSS_DTOR_ITERATIONS

from somewhere.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-25 23:26           ` Jens Gustedt
@ 2014-07-26  2:24             ` Rich Felker
  2014-07-26  7:16               ` Jens Gustedt
  0 siblings, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-26  2:24 UTC (permalink / raw)
  To: musl

On Sat, Jul 26, 2014 at 01:26:09AM +0200, Jens Gustedt wrote:
> Am Freitag, den 25.07.2014, 18:19 -0400 schrieb Rich Felker:
> > Since glibc is going that way, I think we should keep the type sizes
> > the same but leave it explicitly undefined to mix calls to C11 and
> > POSIX functions on the same synchronization objects.
> 
> yes, defitively. Not even for the synchronization functions, basically
> none from pthread and C11 thread should be mixed, I think. I thought
> of figuring out a way to make this even a link error.

What do you mean? If you meant that calling C11 thread functions and
POSIX thread functions in the same program should be an error, I think
that's very wrong. The next issue of POSIX will be aligned with C11,
so both sets of interfaces will exist. Even if not for that, though,
it's just wrong conceptually to exclude the use of both. For example a
library written to ISO C could be using threads (C11 threads)
internally as an implementation detail, and this should not break a
caller which is using POSIX threads.

> > Could you elaborate? Perhaps we're thinking of different things.
> 
> probably.
> 
> The C11 specification is so bad, that some of the functions don't even
> have a semantic description of what they are supposed to achieve. E.g
> tss_t completely lacks a description of what a destructor is, what
> the "iterations" in TSS_DTOR_ITERATIONS describe etc. Parts of it are
> or will be adressed TC, but there is much more. I wrote my findings up
> here
> 
> http://gustedt.wordpress.com/2012/10/14/c11-defects-c-threads-are-not-realizable-with-posix-threads/

Thanks -- I'll check it out.

> > One aspect is that all POSIX synchronization functions are full
> > barriers, whereas presumably the C11 ones are proper acquire/release
> > barriers as appropriate for the operation being performed.
> 
> That is probably the intention. But e.g mtx_lock is only required to
> synchronize with calls to mtx_unlock, not with other calls to mtx_lock
> or similar. The term "lock" isn't even defined.

...

> > Another is Austin Group issue #755, which I'm hoping the WG14 will not
> > rule the same way on. The Austin Group's resolution for POSIX mutexes
> > makes recursive and error-checking mutexes very expensive and requires
> > threads to maintain a record of all such mutexes they own. I have not
> > yet implemented this in musl but I plan to do so soon (BTW this needs
> > to be added to the roadmap).
> 
> I am not sure that I completely understand what this is about. But in
> any case, C threads don't have error checking :)

It's about what happens when a thread exits whole holding a recursive
or errorchecking mutex. If the ownership of that mutex is tracked by a
thread id stored in the mutex (this is the only practical way to do
it), a newly created thread could wrongly become the owner of the
orphaned mutex just by getting the same thread id (by chance). The
only implementation options to avoid this are to have thread ids so
large that values never have to be reused, or to track the list of
mutexes owned by a thread so that it can change the owner to a dummy
value that will never match when it exits.

The obvious way to avoid this problem would be to add to the
specification:

"If a thread exits while it is the owner of a mutex, the behavior is
undefined."

Unfortunately the Austin Group did not want to do this. I'm hoping
someone can raise the issue with WG14 and that they'll decide
differently for C11 threads, so that C11 recursive mutexes can be more
efficient.

For POSIX mutexes, we're basically going to have to treat recursive
and errorchecking mutexes as robust mutexes to meet the requirements
of the standard, despite these requirements only affecting broken
programs that leave mutexes locked (and thus permanently locked) when
a thread exits.

> > > The advantages that I see that this doesn't need all that attr stuff
> > > and has no concept of cancellation.
> > 
> > Cancellation is rather irrelevant to the synchronization primitives.
> > Obviously C11's lack of cancellation makes C11 threads much easier to
> > implement if you're not also doing POSIX threads, but if you're doing
> > both, the fact that C11 lacks a cancellation function makes almost no
> > difference (just one simple cleanup function in condvar wait).
> 
> There is a bit more, maybe. __timedwait does cleanup push and pop and
> messes around with cancelbuf. (But probably I just don't understand
> enough what's going on, here.)

That's just to avoid having two different versions of __timedwait.
It's used for condvar wait, join, and a few other operations which are
cancellable. For mutexes the cancellation feature of __timedwait is
not used.

> In any case, without attributes and possible cancelation, thrd_create
> becomes significantly shorter than pthread_create.

The vast majority of the code in pthread_create is setting up the
stack, TLS, POSIX TSD, and the contents of the __pthread structure
(called TCB on other implementations). Attributes are a pretty small
part.

> And to my limited experience having well defined atomics that are
> integrated in the language, often helps to completely avoid mutexes
> and conditions.

I'm not sure about that. Atomics are mostly useful for the situations
where spinlocks would suffice. They don't help anywhere you would
expect a "wait" operation to happen (e.q. waiting for a queue to
become non-empty or non-full).

> > > > and definitely allows smaller size if the application
> > > > only uses them (but of course makes libc.a and libc.so larger).
> > > 
> > > If we use weak aliases, this basically blows up the symbol table a
> > > bit.
> > > 
> > > When I strip my test executable, it is impressively small.
> > 
> > Yes, this is one reason I don't want __-prefixed symbols for
> > everything, just functions that really _need_ namespace-safe versions.
> > We should probably do some linking tests against all the C11 functions
> > to make sure they're not pulling in functions outside the C11
> > namespace and add __-prefixed versions of those functions only, rather
> > than preemptively trying to guess what needs protection.
> 
> I tried to do that already.

OK.

> > > > > For the types this should be easy to have them typedef'ed to some
> > > > > opaque struct.
> > > > 
> > > > For the types that vary per-arch, I don't see any way around having
> > > > them in the alltypes.h.in bits.
> > > 
> > > The only types that seem to be in bits are mutex and condition. All
> > > others seem to be arch independent.
> > 
> > Ah yes the others are probably not needed for C11.
> > 
> > > On the long we should probably have __pthread names in the alltypes.h
> > > files and typedef these in pthread.h and threads.h respectively.
> > 
> > That doesn't work because both sys/types.h and pthread.h have to
> > expose the pthread names.
> > 
> > > > As for the constants, which ones are
> > > > you talking about?
> > > 
> > > the mtx_ constants are the critical ones.
> > > 
> > > thrd_error and friends can easily be mapped to EXXX error codes from
> > > errno.h. Since these names are all reserved anyway, including errno.h
> > > shouldn't do much harm.
> > 
> > I don't think including errno.h implicitly is permitted. E* is only
> > reserved when errno.h is included. Anyway this is somewhere we wasnt
> > to agree with glibc on the values; I suspect they'll just use values
> > 1,2,... rather than errno codes. If so, that means we really need a
> > wrapper function rather than just an alias.
> 
> Hm, not sure that I follow.
> 
> I only need EBUSY, EINVAL, ENOMEM, and ETIMEDOUT, and effectively only
> that these are consistent with the rest of the C library, which for
> this implementation of C threads will always be musl.

The point of ABI compatibility is that (at this point just some)
binaries and (more importantly) shared libraries without source that
were built/linked against glibc can be used with musl. But for this to
work, the values of the constants need to be the same.

> > > > I don't think it's so easy to directly use the
> > > > POSIX ones for C11 since they have some different semantics (flag bits
> > > > vs enumeration-style) for a few.
> > > 
> > > the mtx_ ones are basically flags, just as the PTHREAD_MUTEX_ ones.
> > > This fits well with the actual values of these in musl.
> > 
> > The PTHREAD_MUTEX_* ones are not flags; each corresponds to a single
> > type and they are not combinable.
> 
> ah, ok, anyhow the only one that I am really interested in is
> PTHREAD_MUTEX_RECURSIVE. So perhaps I can push that down to the
> implementation.

mtx_init needs to be a wrapper for pthread_mutex_init rather than an
alias anyway, since mtx_init takes an integer and pthread_mutex_init
takes a pointer to an attribute object.

> > The C11 ones are combinable, but mtx_timed is useless
> 
> yes, I think I already noted that in the file that I attached to my
> initial mail
> 
> > -- there's no need to care whether it will be
> > used for timed operations when it's initialized.
> > 
> > BTW n1570 only has 4 possible values to pass to mtx_init, but reads
> > (7.26.4.2 p2):
> > 
> > "The mtx_init function creates a mutex object with properties
> > indicated by type, which must have one of the six values:"
> > 
> > Any idea if six is just a mistake or if there are some values missing
> > from the list?
> 
> It is just a leftover, and has/willbe been corrected.
> 
> To summarize, I'd need to get
> 
> EBUSY, EINVAL, ENOMEM, ETIMEDOUT and TSS_DTOR_ITERATIONS

TSS_DTOR_ITERATIONS can just be defined to whatever the right value is
-- IIRC we use the minimum POSIX requires. It doesn't need to
magically sync with something else. If we ever need to change it we
can change both.

Obviously if the error values are used directly, duplicating them in
another header is more trouble since they vary per-arch. This is part
of why I would actually prefer not to use them for the thread function
result codes, but which we do will depend on which way glibc does it.
I can check in with them and see if they have a plan yet.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  2:24             ` Rich Felker
@ 2014-07-26  7:16               ` Jens Gustedt
  2014-07-26  7:35                 ` Rich Felker
  2014-07-26 15:48                 ` Jens Gustedt
  0 siblings, 2 replies; 21+ messages in thread
From: Jens Gustedt @ 2014-07-26  7:16 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 5585 bytes --]

Am Freitag, den 25.07.2014, 22:24 -0400 schrieb Rich Felker:
> > yes, defitively. Not even for the synchronization functions, basically
> > none from pthread and C11 thread should be mixed, I think. I thought
> > of figuring out a way to make this even a link error.
> 
> What do you mean? If you meant that calling C11 thread functions and
> POSIX thread functions in the same program should be an error, I think
> that's very wrong.

Yes, I meant that.

> The next issue of POSIX will be aligned with C11,
> so both sets of interfaces will exist. Even if not for that, though,
> it's just wrong conceptually to exclude the use of both. For example a
> library written to ISO C could be using threads (C11 threads)
> internally as an implementation detail, and this should not break a
> caller which is using POSIX threads.

Ok, didn't occur to me. Thinking of it, even the C library is allowed
to use C threads to accelerate things, as long as it follows the as-if
rule.

> It's about what happens when a thread exits whole holding a recursive
> or errorchecking mutex. If the ownership of that mutex is tracked by a
> thread id stored in the mutex (this is the only practical way to do
> it), a newly created thread could wrongly become the owner of the
> orphaned mutex just by getting the same thread id (by chance). The
> only implementation options to avoid this are to have thread ids so
> large that values never have to be reused, or to track the list of
> mutexes owned by a thread so that it can change the owner to a dummy
> value that will never match when it exits.
> 
> The obvious way to avoid this problem would be to add to the
> specification:
> 
> "If a thread exits while it is the owner of a mutex, the behavior is
> undefined."

noted, I'll watch that something in that sense is included.

Probably this would need a bit more precision about "exits", I would
prefer to use "terminates". A thread terminates not necessarily
immediately after it returns or calls "thrd_exit", the tss destructors
should be called still from the same thread.

We should allow a thread to cleanup its mess with tss destructors.

> > And to my limited experience having well defined atomics that are
> > integrated in the language, often helps to completely avoid mutexes
> > and conditions.
> 
> I'm not sure about that. Atomics are mostly useful for the situations
> where spinlocks would suffice. They don't help anywhere you would
> expect a "wait" operation to happen (e.q. waiting for a queue to
> become non-empty or non-full).

Probably we have complementary experiences. Many uses of mutexes and
conditions in application code are about sharing and updating shared
resources. Often the resource protected is just a counter or other
small data. Especially counters are much better served with atomics.

And you are right mentioning that, in many situations spin locks do
effectively suffice. C11 has atomic_flag for that. Often locks are
just taken for critical sections of code that do a small task, just
some instructions.

> > I only need EBUSY, EINVAL, ENOMEM, and ETIMEDOUT, and effectively only
> > that these are consistent with the rest of the C library, which for
> > this implementation of C threads will always be musl.
> 
> The point of ABI compatibility is that (at this point just some)
> binaries and (more importantly) shared libraries without source that
> were built/linked against glibc can be used with musl. But for this to
> work, the values of the constants need to be the same.

yes, I am aware of that. That is why it is important to have the
thrd-constants and the E-constants in line.

The approach with weak aliases only works if the return codes of the
functions agree. We need

enum {
  thrd_success = 0,
  thrd_busy = EBUSY,
  thrd_error = EINVAL,
  thrd_nomem = ENOMEM,
  thrd_timedout = ETIMEDOUT,
};

and I don't think that there is much of a sensible way to do that
differently. Already the naming of the constants suggest that these
are the values that people (who?) had in mind when designing these
interfaces.

> mtx_init needs to be a wrapper for pthread_mutex_init rather than an
> alias anyway, since mtx_init takes an integer and pthread_mutex_init
> takes a pointer to an attribute object.

sure

> TSS_DTOR_ITERATIONS can just be defined to whatever the right value is
> -- IIRC we use the minimum POSIX requires. It doesn't need to
> magically sync with something else. If we ever need to change it we
> can change both.

ok

> Obviously if the error values are used directly, duplicating them in
> another header is more trouble since they vary per-arch. This is part
> of why I would actually prefer not to use them for the thread function
> result codes, but which we do will depend on which way glibc does it.
> I can check in with them and see if they have a plan yet.

yes, that would be good

I, on my site, will try to have something added to the C specification
that threads.h also includes errno.h. For the moment it is only
specified that it does so with time.h.

Perhaps it would even be good to have the thrd-constants also be
exported by errno.h. These are error codes, finally.


Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  7:16               ` Jens Gustedt
@ 2014-07-26  7:35                 ` Rich Felker
  2014-07-26  8:32                   ` Jens Gustedt
  2014-07-26 15:48                 ` Jens Gustedt
  1 sibling, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-26  7:35 UTC (permalink / raw)
  To: musl

On Sat, Jul 26, 2014 at 09:16:40AM +0200, Jens Gustedt wrote:
> > It's about what happens when a thread exits whole holding a recursive
> > or errorchecking mutex. If the ownership of that mutex is tracked by a
> > thread id stored in the mutex (this is the only practical way to do
> > it), a newly created thread could wrongly become the owner of the
> > orphaned mutex just by getting the same thread id (by chance). The
> > only implementation options to avoid this are to have thread ids so
> > large that values never have to be reused, or to track the list of
> > mutexes owned by a thread so that it can change the owner to a dummy
> > value that will never match when it exits.
> > 
> > The obvious way to avoid this problem would be to add to the
> > specification:
> > 
> > "If a thread exits while it is the owner of a mutex, the behavior is
> > undefined."
> 
> noted, I'll watch that something in that sense is included.
> 
> Probably this would need a bit more precision about "exits", I would
> prefer to use "terminates". A thread terminates not necessarily
> immediately after it returns or calls "thrd_exit", the tss destructors
> should be called still from the same thread.
> 
> We should allow a thread to cleanup its mess with tss destructors.

Yes, I agree completely that "terminates" is the right wording.

> > > And to my limited experience having well defined atomics that are
> > > integrated in the language, often helps to completely avoid mutexes
> > > and conditions.
> > 
> > I'm not sure about that. Atomics are mostly useful for the situations
> > where spinlocks would suffice. They don't help anywhere you would
> > expect a "wait" operation to happen (e.q. waiting for a queue to
> > become non-empty or non-full).
> 
> Probably we have complementary experiences. Many uses of mutexes and
> conditions in application code are about sharing and updating shared
> resources. Often the resource protected is just a counter or other
> small data. Especially counters are much better served with atomics.
> 
> And you are right mentioning that, in many situations spin locks do
> effectively suffice. C11 has atomic_flag for that. Often locks are
> just taken for critical sections of code that do a small task, just
> some instructions.

I wasn't trying to say that spinlocks suffice in place of atomics, but
rather that atomics can rarely replace synchronization primitives, and
that in situations where you can't use a spinlock (because you expect
it to be waiting a long time for the lock, or because you want to do a
lot with the lock held) atomics are unlikely to solve the problem.

> > > I only need EBUSY, EINVAL, ENOMEM, and ETIMEDOUT, and effectively only
> > > that these are consistent with the rest of the C library, which for
> > > this implementation of C threads will always be musl.
> > 
> > The point of ABI compatibility is that (at this point just some)
> > binaries and (more importantly) shared libraries without source that
> > were built/linked against glibc can be used with musl. But for this to
> > work, the values of the constants need to be the same.
> 
> yes, I am aware of that. That is why it is important to have the
> thrd-constants and the E-constants in line.
> 
> The approach with weak aliases only works if the return codes of the
> functions agree. We need
> 
> enum {
>   thrd_success = 0,
>   thrd_busy = EBUSY,
>   thrd_error = EINVAL,
>   thrd_nomem = ENOMEM,
>   thrd_timedout = ETIMEDOUT,
> };
> 
> and I don't think that there is much of a sensible way to do that
> differently. Already the naming of the constants suggest that these
> are the values that people (who?) had in mind when designing these
> interfaces.

Actually, I disagree with your mappings. thrd_error is not going to
come from EINVAL (IIRC the only place POSIX specifies EINVAL anyway is
as an optional error when you already invoked UB) but rather from
attempting to lock a recursive mutex when the count is already maxed
out. And thrd_nomem is not going to come from ENOMEM, since
pthread_create returns EAGAIN, not ENOMEM, when memory for the thread
cannot be allocated.

With this in mind, your idea of using errno codes is seeming less and
less reasonable to me.

For reference, here's a summary of the only possible errors I see:

thrd_timedout - for timed operations

thrd_busy - for mtx_trylock

thrd_error - for mtx_lock or trylock (maxed recursive lock count), or
tss_create (no more tss slots)

thrd_nomem - for thrd_create

All of the other cases looked like things that cannot happen with musl
(or with any reasonable implementation).

> > Obviously if the error values are used directly, duplicating them in
> > another header is more trouble since they vary per-arch. This is part
> > of why I would actually prefer not to use them for the thread function
> > result codes, but which we do will depend on which way glibc does it.
> > I can check in with them and see if they have a plan yet.
> 
> yes, that would be good
> 
> I, on my site, will try to have something added to the C specification
> that threads.h also includes errno.h. For the moment it is only
> specified that it does so with time.h.
> 
> Perhaps it would even be good to have the thrd-constants also be
> exported by errno.h. These are error codes, finally.

I disagree here. There are many different kinds of result codes in C
and POSIX which are in different domains. If the thrd_* result codes
had been intended to be in the same domain as errno values, these
functions would have just been specified to return errno values. It's
possible that they might match errno values, but that's certainly an
implementation detail, not something that applications could
reasonably depend on, and therefore I think it makes no sense to
require or allow threads.h to expose errno.h.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  7:35                 ` Rich Felker
@ 2014-07-26  8:32                   ` Jens Gustedt
  2014-07-26  9:03                     ` Rich Felker
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-26  8:32 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 5557 bytes --]

Am Samstag, den 26.07.2014, 03:35 -0400 schrieb Rich Felker:
> On Sat, Jul 26, 2014 at 09:16:40AM +0200, Jens Gustedt wrote:
> > The approach with weak aliases only works if the return codes of the
> > functions agree. We need
> > 
> > enum {
> >   thrd_success = 0,
> >   thrd_busy = EBUSY,
> >   thrd_error = EINVAL,
> >   thrd_nomem = ENOMEM,
> >   thrd_timedout = ETIMEDOUT,
> > };
> > 
> > and I don't think that there is much of a sensible way to do that
> > differently. Already the naming of the constants suggest that these
> > are the values that people (who?) had in mind when designing these
> > interfaces.
> 
> Actually, I disagree with your mappings. thrd_error is not going to
> come from EINVAL (IIRC the only place POSIX specifies EINVAL anyway is
> as an optional error when you already invoked UB) but rather from
> attempting to lock a recursive mutex when the count is already maxed
> out.

I checked for all the functions that I marked for being suitable to be
aliased and that return int, and my impression was EINVAl was the only
error that could occur and that it was consistent with
thrd_error, and that other return values from POSIX functions such as
EDEADLK decribe behavior that is UB for C11.

But it seems I missed EAGAIN for recursive mutexes. I will reconsider.

> And thrd_nomem is not going to come from ENOMEM, since
> pthread_create returns EAGAIN, not ENOMEM, when memory for the thread
> cannot be allocated.

thrd_create can't be an alias, anyhow, so there is no problem in
translating return values.

(BTW, the C11 semantics for what thrd_nomem would mean are fuzzy
enought that returning thrd_error in all error cases would be
sufficient, I think)

Other functions that have return conventions that are not easily to
bring in line with POSIX are mtx_unlock and thrd_sleep, so they need
wrappers, too.


> With this in mind, your idea of using errno codes is seeming less and
> less reasonable to me.
> 
> For reference, here's a summary of the only possible errors I see:
> 
> thrd_timedout - for timed operations
> 
> thrd_busy - for mtx_trylock
> 
> thrd_error - for mtx_lock or trylock (maxed recursive lock count), or
> tss_create (no more tss slots)
> 
> thrd_nomem - for thrd_create
> 
> All of the other cases looked like things that cannot happen with musl
> (or with any reasonable implementation).
> 
> > > Obviously if the error values are used directly, duplicating them in
> > > another header is more trouble since they vary per-arch. This is part
> > > of why I would actually prefer not to use them for the thread function
> > > result codes, but which we do will depend on which way glibc does it.
> > > I can check in with them and see if they have a plan yet.
> > 
> > yes, that would be good
> > 
> > I, on my site, will try to have something added to the C specification
> > that threads.h also includes errno.h. For the moment it is only
> > specified that it does so with time.h.
> > 
> > Perhaps it would even be good to have the thrd-constants also be
> > exported by errno.h. These are error codes, finally.
> 
> I disagree here. There are many different kinds of result codes in C
> and POSIX which are in different domains. If the thrd_* result codes
> had been intended to be in the same domain as errno values, these
> functions would have just been specified to return errno values.

no.

Whereas you can normally suppose that additions to the C standard are
deeply discussed for all their implications with the existing parts,
historically this seems not to be the case for C11 threads.

The interface specification is just an artefact of being the one of a
proprietary library that existed at that time. That one had the
head-start of having two members of the committee being the owners of
the company that owns that library. (Probably these people had good
intentions, though. The discussion between the committee and the C
user community is simply not organized well.)

The starting point for C11 threads just was the reference manual of
that library, and the process of standardization only corrected the
most obvious incoherences. (E.g the fact that it used (but didn't
define) yet another type to specify times.)

Anybody with reason and with knowledge of POSIX and C (which are
standards from the same organization, ISO) would just have specified
error codes in line with pthreads. There are not many places in the
standard that uses enumeration constants for a similar purpose, and it
has not much of an advantage. There is the general requirement of the
standard that all constant integer expressions that it defines must be
testable by the preprocessor.

> It's
> possible that they might match errno values, but that's certainly an
> implementation detail, not something that applications could
> reasonably depend on, and therefore I think it makes no sense to
> require or allow threads.h to expose errno.h.

As you can see I strongly disagree here. We shouldn't introduce values
that semantically serve as error return values of library functions
and that are not regulated by errno.h and that aren't fixed in
compilation phase 3.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  8:32                   ` Jens Gustedt
@ 2014-07-26  9:03                     ` Rich Felker
  2014-07-26 11:15                       ` Jens Gustedt
  0 siblings, 1 reply; 21+ messages in thread
From: Rich Felker @ 2014-07-26  9:03 UTC (permalink / raw)
  To: musl

On Sat, Jul 26, 2014 at 10:32:55AM +0200, Jens Gustedt wrote:
> Anybody with reason and with knowledge of POSIX and C (which are
> standards from the same organization, ISO) would just have specified
> error codes in line with pthreads. There are not many places in the
> standard that uses enumeration constants for a similar purpose, and it
> has not much of an advantage. There is the general requirement of the
> standard that all constant integer expressions that it defines must be
> testable by the preprocessor.

I agree that they're ugly and contrary to style used elsewhere in the
standard, but I don't see how cross-polluting this mess with errno.h
makes it any less offensive.

> > It's
> > possible that they might match errno values, but that's certainly an
> > implementation detail, not something that applications could
> > reasonably depend on, and therefore I think it makes no sense to
> > require or allow threads.h to expose errno.h.
> 
> As you can see I strongly disagree here. We shouldn't introduce values
> that semantically serve as error return values of library functions
> and that are not regulated by errno.h and that aren't fixed in
> compilation phase 3.

Is this just ideological? POSIX has plenty of such values, such as the
GAI_*, REG_*, FNM_*, WRDE_*, etc. result codes. Maybe there are not
many (any?) in plain C, but C11 added them and I don't think there's
any use in trying to change it now...

Also C has no precedent for _returning_ error codes (excluding of
course Annex K); the errno.h constants are only used with the errno
object.

Rich


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  9:03                     ` Rich Felker
@ 2014-07-26 11:15                       ` Jens Gustedt
  0 siblings, 0 replies; 21+ messages in thread
From: Jens Gustedt @ 2014-07-26 11:15 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 2723 bytes --]

Am Samstag, den 26.07.2014, 05:03 -0400 schrieb Rich Felker:
> On Sat, Jul 26, 2014 at 10:32:55AM +0200, Jens Gustedt wrote:
> > Anybody with reason and with knowledge of POSIX and C (which are
> > standards from the same organization, ISO) would just have specified
> > error codes in line with pthreads. There are not many places in the
> > standard that uses enumeration constants for a similar purpose, and it
> > has not much of an advantage. There is the general requirement of the
> > standard that all constant integer expressions that it defines must be
> > testable by the preprocessor.
> 
> I agree that they're ugly and contrary to style used elsewhere in the
> standard, but I don't see how cross-polluting this mess with errno.h
> makes it any less offensive.

It just makes it easier for implementations to chose a consistent set
of values.

> > As you can see I strongly disagree here. We shouldn't introduce values
> > that semantically serve as error return values of library functions
> > and that are not regulated by errno.h and that aren't fixed in
> > compilation phase 3.
> 
> Is this just ideological?

probably :)

> POSIX has plenty of such values, such as the
> GAI_*, REG_*, FNM_*, WRDE_*, etc. result codes. Maybe there are not
> many (any?) in plain C, but C11 added them and I don't think there's
> any use in trying to change it now...

POSIX seems to be a little less restrictive than C, here. It uses the
term "symbolic constant" where C always uses the term "macro"
consistenly all over the place, with threads.h and atomic.h the only
exceptions in using enumerations. And C has the explicit requirement
that all macros that are defined by the standard to resolve to an
"integer constant expression" be such that they can be used in
preprocessor directives.

> Also C has no precedent for _returning_ error codes (excluding of
> course Annex K); the errno.h constants are only used with the errno
> object.

Exactly, so they got it really bad by having added two optional parts
that don't agree on that handling, and that don't even aggree with
themselves. (thrd_sleep has yet another convention, -1 for interrupt
and other negative value for unspecified "failure", and timespec_get
gratuously uses the time base as a return value on success)

What a mess. I'll try to come up with a solution that is the least
intrusive.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: C11 threads
  2014-07-26  7:16               ` Jens Gustedt
  2014-07-26  7:35                 ` Rich Felker
@ 2014-07-26 15:48                 ` Jens Gustedt
  1 sibling, 0 replies; 21+ messages in thread
From: Jens Gustedt @ 2014-07-26 15:48 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1042 bytes --]

Am Samstag, den 26.07.2014, 09:16 +0200 schrieb Jens Gustedt:
> And you are right mentioning that, in many situations spin locks do
> effectively suffice. C11 has atomic_flag for that. Often locks are
> just taken for critical sections of code that do a small task, just
> some instructions.

Curiously, I just tracked down a use of pthread_mutex_lock and
pthread_mutex_unlock that I couldn't explain. It came from libatomic
as of gcc-4.9.0.

Looking into that, I see that they got the locking part for the non
lock-free atomics in their POSIX version plain wrong. Not only that
this sucks in the symbols which they shouldn't, but pthread_mutex_t is
just not the right tool for the task. It should be atomic_flag.

Jens

-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::



[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-07-26 15:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-25 10:00 C11 threads Jens Gustedt
2014-07-25 10:40 ` Szabolcs Nagy
2014-07-25 11:06   ` Jens Gustedt
2014-07-25 13:04     ` Szabolcs Nagy
2014-07-25 13:38       ` Jens Gustedt
2014-07-25 13:42       ` Morten Welinder
2014-07-25 14:15         ` Szabolcs Nagy
2014-07-25 16:14       ` Rich Felker
2014-07-25 21:59         ` Jens Gustedt
2014-07-25 22:25           ` Rich Felker
2014-07-25 15:41     ` Rich Felker
2014-07-25 17:10       ` Jens Gustedt
2014-07-25 22:19         ` Rich Felker
2014-07-25 23:26           ` Jens Gustedt
2014-07-26  2:24             ` Rich Felker
2014-07-26  7:16               ` Jens Gustedt
2014-07-26  7:35                 ` Rich Felker
2014-07-26  8:32                   ` Jens Gustedt
2014-07-26  9:03                     ` Rich Felker
2014-07-26 11:15                       ` Jens Gustedt
2014-07-26 15:48                 ` Jens Gustedt

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).