diff mbox series

[v8,1/8] nptl: Add C11 threads thrd_* functions

Message ID 1517591084-11347-2-git-send-email-adhemerval.zanella@linaro.org
State New
Headers show
Series Add support for ISO C threads.h | expand

Commit Message

Adhemerval Zanella Netto Feb. 2, 2018, 5:04 p.m. UTC
This patch adds the thrd_* definitions from C11 threads (ISO/IEC 9899:2011),
more specifically thrd_create, thrd_curent, rhd_detach, thrd_equal,
thrd_exit, thrd_join, thrd_sleep, thrd_yield, and required types.

Mostly of the definitions are composed based on POSIX conterparts, such as
thrd_t (using pthread_t).  For thrd_* function internally direct
POSIX pthread call are used with the exceptions:

  1. thrd_start uses pthread_create internal implementation, but changes
     how to actually calls the start routine.  This is due the difference
     in signature between POSIX and C11, where former return a 'void *'
     and latter 'int'.
     To avoid calling convention issues due 'void *' to int cast, routines
     from C11 threads are started slight different than default pthread one.
     Explicit cast to expected return are used internally on pthread_create
     and the result is stored back to void also with an explicit cast.

  2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering
     errno, to handle expected standard return codes, and to avoid making
     the call a POSIX cancellation entrypoint.

  3. thrd_yield also uses internal direct syscall to avoid errno clobbering.

Checked with a build for all major ABI (aarch64-linux-gnu, alpha-linux-gnu,
arm-linux-gnueabi, i386-linux-gnu, ia64-linux-gnu, m68k-linux-gnu,
microblaze-linux-gnu [1], mips{64}-linux-gnu, nios2-linux-gnu,
powerpc{64le}-linux-gnu, s390{x}-linux-gnu, sparc{64}-linux-gnu,
tile{pro,gx}-linux-gnu, and x86_64-linux-gnu).

Also ran a full check on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu,
arm-linux-gnueabhf, and powerpc64le-linux-gnu.

	* conform/Makefile (conformtest-headers-ISO11): Add threads.h.
	(linknamespace-libs-ISO11): Add libpthread.a.
	* conform/data/threads.h-data: New file: add C11 thrd_* types and
	functions.
	* include/stdc-predef.h (__STDC_NO_THREADS__): Remove definition.
	* nptl/Makefile (headers): Add threads.h.
	(libpthread-routines): Add new C11 thread thrd_create, thrd_current,
	thrd_detach, thrd_equal, thrd_exit, thrd_join, thrd_sleep, and
	thrd_yield.
	* nptl/Versions (libpthread) [GLIBC_2.27]): Add new C11 thread
	thrd_create, thrd_current, thrd_detach, thrd_equal, thrd_exit,
	thrd_join, thrd_sleep, and thrd_yield symbols.
	* nptl/descr.h (struct pthread): Add c11 field.
	* nptl/pthreadP.h (ATTR_C11_THREAD): New define.
	* nptl/pthread_create.c (START_THREAD_DEFN): Call C11 thread start
	routine with expected function prototype.
	(__pthread_create_2_1): Add C11 threads check based on attribute
	value.
	* nptl/thrd_create.c: New file.
	* nptl/thrd_current.c: Likewise.
	* nptl/thrd_detach.c: Likewise.
	* nptl/thrd_equal.c: Likewise.
	* nptl/thrd_exit.c: Likewise.
	* nptl/thrd_join.c: Likewise.
	* nptl/thrd_priv.h: Likewise.
	* nptl/thrd_sleep.c: Likewise.
	* nptl/thrd_yield.c: Likewise.
	* sysdeps/nptl/threads.h: Likewise.
---
 ChangeLog                   | 31 ++++++++++++++++
 conform/Makefile            |  7 ++--
 conform/data/threads.h-data | 23 ++++++++++++
 include/stdc-predef.h       |  3 --
 nptl/Makefile               |  6 ++-
 nptl/Versions               |  6 +++
 nptl/descr.h                |  2 +
 nptl/pthreadP.h             |  3 ++
 nptl/pthread_create.c       | 18 ++++++++-
 nptl/thrd_create.c          | 29 +++++++++++++++
 nptl/thrd_current.c         | 25 +++++++++++++
 nptl/thrd_detach.c          | 28 ++++++++++++++
 nptl/thrd_equal.c           | 25 +++++++++++++
 nptl/thrd_exit.c            | 25 +++++++++++++
 nptl/thrd_join.c            | 30 +++++++++++++++
 nptl/thrd_priv.h            | 45 +++++++++++++++++++++++
 nptl/thrd_sleep.c           | 38 +++++++++++++++++++
 nptl/thrd_yield.c           | 26 +++++++++++++
 sysdeps/nptl/threads.h      | 90 +++++++++++++++++++++++++++++++++++++++++++++
 19 files changed, 450 insertions(+), 10 deletions(-)
 create mode 100644 conform/data/threads.h-data
 create mode 100644 nptl/thrd_create.c
 create mode 100644 nptl/thrd_current.c
 create mode 100644 nptl/thrd_detach.c
 create mode 100644 nptl/thrd_equal.c
 create mode 100644 nptl/thrd_exit.c
 create mode 100644 nptl/thrd_join.c
 create mode 100644 nptl/thrd_priv.h
 create mode 100644 nptl/thrd_sleep.c
 create mode 100644 nptl/thrd_yield.c
 create mode 100644 sysdeps/nptl/threads.h

-- 
2.7.4

Comments

Gabriel F. T. Gomes Feb. 8, 2018, 1:49 p.m. UTC | #1
I have only a few, minor comments.

On Fri, 02 Feb 2018, Adhemerval Zanella wrote:

>-/* We do not support C11 <threads.h>.  */

>-#define __STDC_NO_THREADS__		1


I don't know if that actually matters, but should you wait until the other
patches in this series (at least patch 2) are in before removing this
definition?

>+int

>+thrd_sleep (const struct timespec* time_point, struct timespec* remaining)

>+{

>+  /* It calls the syscalls directly to avoid cancellable version.  */

>+  INTERNAL_SYSCALL_DECL (err);

>+  int ret = INTERNAL_SYSCALL_CALL (nanosleep, err, time_point, remaining);

>+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))

>+    {

>+      /* C11 states thrd_sleep function returns -1 if it has been interrupted

>+         by a signal, or a negative value if it fails.  */

  ~~~~~~~~~
This hunk did not apply with git am, because there are more than 8 spaces.

>+/* Detach the thread identified by __THR from the current environment

>+   (tt does not allow join or wait for it).  */

      ~~
Did you mean "it"?  Or is "tt" something else that I did not understand.
Adhemerval Zanella Netto Feb. 9, 2018, 10:56 a.m. UTC | #2
On 08/02/2018 11:49, Gabriel F. T. Gomes wrote:
> I have only a few, minor comments.

> 

> On Fri, 02 Feb 2018, Adhemerval Zanella wrote:

> 

>> -/* We do not support C11 <threads.h>.  */

>> -#define __STDC_NO_THREADS__		1

> 

> I don't know if that actually matters, but should you wait until the other

> patches in this series (at least patch 2) are in before removing this

> definition?

>


I do not have a strong opinion about when to remove __STDC_NO_THREADS__, since
my idea is first get all patches reviewed and acked before actually commit then.

 
>> +int

>> +thrd_sleep (const struct timespec* time_point, struct timespec* remaining)

>> +{

>> +  /* It calls the syscalls directly to avoid cancellable version.  */

>> +  INTERNAL_SYSCALL_DECL (err);

>> +  int ret = INTERNAL_SYSCALL_CALL (nanosleep, err, time_point, remaining);

>> +  if (INTERNAL_SYSCALL_ERROR_P (ret, err))

>> +    {

>> +      /* C11 states thrd_sleep function returns -1 if it has been interrupted

>> +         by a signal, or a negative value if it fails.  */

>   ~~~~~~~~~

> This hunk did not apply with git am, because there are more than 8 spaces.


Thanks, I fixed it locally (I also keep my user branch in sync [1]).

> 

>> +/* Detach the thread identified by __THR from the current environment

>> +   (tt does not allow join or wait for it).  */

>       ~~

> Did you mean "it"?  Or is "tt" something else that I did not understand.

> 


It should be 'it', fixed it locally.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/c11-threads
Gabriel F. T. Gomes Feb. 26, 2018, 12:28 p.m. UTC | #3
On Fri, 09 Feb 2018, Adhemerval Zanella wrote:
>On 08/02/2018 11:49, Gabriel F. T. Gomes wrote:

>> On Fri, 02 Feb 2018, Adhemerval Zanella wrote:

>>   

>>> -/* We do not support C11 <threads.h>.  */

>>> -#define __STDC_NO_THREADS__		1  

>> 

>> I don't know if that actually matters, but should you wait until the other

>> patches in this series (at least patch 2) are in before removing this

>> definition?

>

>I do not have a strong opinion about when to remove __STDC_NO_THREADS__, since

>my idea is first get all patches reviewed and acked before actually commit then.


Fair enough.

I also reviewed the other patches in this set, and I don't have further
comments other than the cosmetic bit below.

(Since I'm definitely *not* an expert at threads, I only checked against
the standard and it looks good to me.  So, please read this review as one
from a novice)


On patch 4:

>+/* Destroy condition variable pointed by __cond and free all of its

>+   resources.  */

>+extern void cnd_destroy (cnd_t *__COND);  

                                  ~~~~~~
Only here, the parameter name is in uppercase (and the comment in
lowercase).  Any special reason to do so?
Florian Weimer July 6, 2018, 12:46 p.m. UTC | #4
On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:
> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>   		      pthread_mutex_getprioceiling \

>   		      pthread_mutex_setprioceiling \

>   		      pthread_setname pthread_getname \

> -		      pthread_setattr_default_np pthread_getattr_default_np

> +		      pthread_setattr_default_np pthread_getattr_default_np \

> +		      thrd_create thrd_current thrd_detach thrd_equal \


thrd_current should live in libc, not in libpthread.  Same for 
thrd_equal, I suppose.  You should just duplicate the comparison, seeing 
that we haven't done that particular cleanup for pthread_equal yet.

Not sure about thrd_sleep and thrd_yield, but I lean towards libc there 
as well.

Thanks,
Florian
Adhemerval Zanella Netto July 10, 2018, 7:26 p.m. UTC | #5
On 06/07/2018 09:46, Florian Weimer wrote:
> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>                 pthread_mutex_getprioceiling \

>>                 pthread_mutex_setprioceiling \

>>                 pthread_setname pthread_getname \

>> -              pthread_setattr_default_np pthread_getattr_default_np

>> +              pthread_setattr_default_np pthread_getattr_default_np \

>> +              thrd_create thrd_current thrd_detach thrd_equal \

> 

> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

> 

> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.


Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and
thrd_yield) to libc on my personal branch [1] (the change is just to move
the objects from libpthread-routines to routines rule in nptl/Makefile).
I also adjusted the abilist patch with the change.


[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/c11-threads
Szabolcs Nagy July 11, 2018, 3:49 p.m. UTC | #6
On 10/07/18 20:26, Adhemerval Zanella wrote:
> 

> 

> On 06/07/2018 09:46, Florian Weimer wrote:

>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>>                  pthread_mutex_getprioceiling \

>>>                  pthread_mutex_setprioceiling \

>>>                  pthread_setname pthread_getname \

>>> -              pthread_setattr_default_np pthread_getattr_default_np

>>> +              pthread_setattr_default_np pthread_getattr_default_np \

>>> +              thrd_create thrd_current thrd_detach thrd_equal \

>>

>> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

>>

>> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.

> 

> Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and

> thrd_yield) to libc on my personal branch [1] (the change is just to move

> the objects from libpthread-routines to routines rule in nptl/Makefile).

> I also adjusted the abilist patch with the change.

> 


the abilist patch seems to add
sysdeps/unix/sysv/linux/tile/tilegx64/libpthread.abilist
i think you can drop that (and update the ChangeLog).

> 

> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/c11-threads

>
Adhemerval Zanella Netto July 11, 2018, 4:24 p.m. UTC | #7
On 11/07/2018 12:49, Szabolcs Nagy wrote:
> On 10/07/18 20:26, Adhemerval Zanella wrote:

>>

>>

>> On 06/07/2018 09:46, Florian Weimer wrote:

>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>>>                  pthread_mutex_getprioceiling \

>>>>                  pthread_mutex_setprioceiling \

>>>>                  pthread_setname pthread_getname \

>>>> -              pthread_setattr_default_np pthread_getattr_default_np

>>>> +              pthread_setattr_default_np pthread_getattr_default_np \

>>>> +              thrd_create thrd_current thrd_detach thrd_equal \

>>>

>>> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

>>>

>>> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.

>>

>> Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and

>> thrd_yield) to libc on my personal branch [1] (the change is just to move

>> the objects from libpthread-routines to routines rule in nptl/Makefile).

>> I also adjusted the abilist patch with the change.

>>

> 

> the abilist patch seems to add

> sysdeps/unix/sysv/linux/tile/tilegx64/libpthread.abilist

> i think you can drop that (and update the ChangeLog).


Thanks for catching this up, I fixed on my personal c11 thread branch.
Florian Weimer July 12, 2018, 12:18 p.m. UTC | #8
On 07/11/2018 06:24 PM, Adhemerval Zanella wrote:
> 

> 

> On 11/07/2018 12:49, Szabolcs Nagy wrote:

>> On 10/07/18 20:26, Adhemerval Zanella wrote:

>>>

>>>

>>> On 06/07/2018 09:46, Florian Weimer wrote:

>>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>>>>                   pthread_mutex_getprioceiling \

>>>>>                   pthread_mutex_setprioceiling \

>>>>>                   pthread_setname pthread_getname \

>>>>> -              pthread_setattr_default_np pthread_getattr_default_np

>>>>> +              pthread_setattr_default_np pthread_getattr_default_np \

>>>>> +              thrd_create thrd_current thrd_detach thrd_equal \

>>>>

>>>> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

>>>>

>>>> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.

>>>

>>> Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and

>>> thrd_yield) to libc on my personal branch [1] (the change is just to move

>>> the objects from libpthread-routines to routines rule in nptl/Makefile).

>>> I also adjusted the abilist patch with the change.

>>>

>>

>> the abilist patch seems to add

>> sysdeps/unix/sysv/linux/tile/tilegx64/libpthread.abilist

>> i think you can drop that (and update the ChangeLog).

> 

> Thanks for catching this up, I fixed on my personal c11 thread branch.


I still see the attached ABI diffs.

There is also a new linknamespace failure on hppa:

[initial] thrd_create -> [libpthread.a(thrd_create.o)] 
__pthread_create_2_1 -> [libpthread.a(pthread_create.o)] mprotect

That should be easy to fix.  I'll post a separate patch for that.

Thanks,
Florian
==> /home/bmg/build/glibcs/i686-gnu/glibc/hurd/check-abi-libhurduser.out <==
--- ../sysdeps/mach/hurd/libhurduser.abilist	2018-07-05 06:10:49.243248916 -0400
+++ /home/bmg/build/glibcs/i686-gnu/glibc/hurd/libhurduser.symlist	2018-07-12 07:38:17.405204797 -0400
@@ -0,0 +1,611 @@
+Base _S_msg_server F
+Base _S_msg_server_routines D 0x64
+Base __auth_getids F
+Base __auth_makeauth F
+Base __auth_server_authenticate F
+Base __auth_user_authenticate F
+Base __bss_start Base g ? D .bss 00000000
+Base __crash_dump_task F
+Base __dir_link F
+Base __dir_lookup F
+Base __dir_mkdir F
+Base __dir_mkfile F
+Base __dir_notice_changes F
+Base __dir_readdir F
+Base __dir_rename F
+Base __dir_rmdir F
+Base __dir_unlink F
+Base __exec_exec F
+Base __exec_exec_paths F
+Base __exec_init F
+Base __exec_setexecdata F
+Base __exec_startup_get_info F
+Base __file_chauthor F
+Base __file_check_access F
+Base __file_chflags F
+Base __file_chmod F
+Base __file_chown F
+Base __file_exec F
+Base __file_exec_paths F
+Base __file_get_fs_options F
+Base __file_get_storage_info F
+Base __file_get_translator F
+Base __file_get_translator_cntl F
+Base __file_getcontrol F
+Base __file_getfh F
+Base __file_getlinknode F
+Base __file_lock F
+Base __file_lock_stat F
+Base __file_notice_changes F
+Base __file_reparent F
+Base __file_set_size F
+Base __file_set_translator F
+Base __file_statfs F
+Base __file_sync F
+Base __file_syncfs F
+Base __file_utimens F
+Base __file_utimes F

==> /home/bmg/build/glibcs/i686-gnu/glibc/mach/check-abi-libmachuser.out <==
--- ../sysdeps/mach/libmachuser.abilist	2018-07-05 06:10:49.254249207 -0400
+++ /home/bmg/build/glibcs/i686-gnu/glibc/mach/libmachuser.symlist	2018-07-12 07:36:45.837658100 -0400
@@ -0,0 +1,319 @@
+Base _S_exc_server F
+Base _S_exc_server_routines D 0x4
+Base __bss_start Base g ? D .bss 00000000
+Base __default_pager_info F
+Base __default_pager_object_create F
+Base __default_pager_object_pages F
+Base __default_pager_objects F
+Base __default_pager_paging_file F
+Base __default_pager_register_fileserver F
+Base __device_close F
+Base __device_get_status F
+Base __device_map F
+Base __device_open F
+Base __device_open_request F
+Base __device_read F
+Base __device_read_inband F
+Base __device_read_request F
+Base __device_read_request_inband F
+Base __device_set_filter F
+Base __device_set_status F
+Base __device_write F
+Base __device_write_inband F
+Base __device_write_request F
+Base __device_write_request_inband F
+Base __exception_raise F
+Base __gsync_requeue F
+Base __gsync_wait F
+Base __gsync_wake F
+Base __host_adjust_time F
+Base __host_get_boot_info F
+Base __host_get_time F
+Base __host_info F
+Base __host_kernel_version F
+Base __host_processor_set_priv F
+Base __host_processor_sets F
+Base __host_processors F
+Base __host_reboot F
+Base __host_set_time F
+Base __i386_get_gdt F
+Base __i386_get_ldt F
+Base __i386_io_perm_create F
+Base __i386_io_perm_modify F
+Base __i386_set_gdt F
+Base __i386_set_ldt F
+Base __mach_notify_new_task F
+Base __mach_port_allocate_name_rpc F
+Base __mach_port_allocate_rpc F

==> /home/bmg/build/glibcs/m68k-linux-gnu-coldfire/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist	2018-07-10 08:15:53.535227613 -0400
+++ /home/bmg/build/glibcs/m68k-linux-gnu-coldfire/glibc/libc.symlist	2018-07-12 07:54:17.126989778 -0400
@@ -122,0 +123,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/m68k-linux-gnu-coldfire/glibc/nptl/check-abi-libpthread.out <==
--- ../sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist	2018-07-12 07:14:24.376165898 -0400
+++ /home/bmg/build/glibcs/m68k-linux-gnu-coldfire/glibc/nptl/libpthread.symlist	2018-07-12 07:44:19.285683784 -0400
@@ -23 +22,0 @@ GLIBC_2.28 thrd_create F
-GLIBC_2.28 thrd_current F
@@ -25 +23,0 @@ GLIBC_2.28 thrd_detach F
-GLIBC_2.28 thrd_equal F
@@ -28,2 +25,0 @@ GLIBC_2.28 thrd_join F
-GLIBC_2.28 thrd_sleep F
-GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/m68k-linux-gnu-coldfire-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist	2018-07-10 08:15:53.535227613 -0400
+++ /home/bmg/build/glibcs/m68k-linux-gnu-coldfire-soft/glibc/libc.symlist	2018-07-12 07:59:42.365934960 -0400
@@ -122,0 +123,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/m68k-linux-gnu-coldfire-soft/glibc/nptl/check-abi-libpthread.out <==
--- ../sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist	2018-07-12 07:14:24.376165898 -0400
+++ /home/bmg/build/glibcs/m68k-linux-gnu-coldfire-soft/glibc/nptl/libpthread.symlist	2018-07-12 07:45:38.102269392 -0400
@@ -23 +22,0 @@ GLIBC_2.28 thrd_create F
-GLIBC_2.28 thrd_current F
@@ -25 +23,0 @@ GLIBC_2.28 thrd_detach F
-GLIBC_2.28 thrd_equal F
@@ -28,2 +25,0 @@ GLIBC_2.28 thrd_join F
-GLIBC_2.28 thrd_sleep F
-GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/mipsel-linux-gnu-nan2008-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist	2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mipsel-linux-gnu-nan2008-soft/glibc/libc.symlist	2018-07-12 08:05:48.875315449 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/mipsel-linux-gnu-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist	2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mipsel-linux-gnu-soft/glibc/libc.symlist	2018-07-12 08:07:26.234527478 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/mips-linux-gnu-nan2008-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist	2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mips-linux-gnu-nan2008-soft/glibc/libc.symlist	2018-07-12 08:03:53.394265775 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/mips-linux-gnu-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist	2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mips-linux-gnu-soft/glibc/libc.symlist	2018-07-12 08:04:43.725036830 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/powerpc-linux-gnu-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist	2018-07-10 08:15:53.537227663 -0400
+++ /home/bmg/build/glibcs/powerpc-linux-gnu-soft/glibc/libc.symlist	2018-07-12 08:07:09.786984849 -0400
@@ -1995,0 +1996,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/powerpc-linux-gnuspe-e500v1/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist	2018-07-10 08:15:53.537227663 -0400
+++ /home/bmg/build/glibcs/powerpc-linux-gnuspe-e500v1/glibc/libc.symlist	2018-07-12 08:07:11.875053737 -0400
@@ -1995,0 +1996,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> /home/bmg/build/glibcs/powerpc-linux-gnuspe/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist	2018-07-10 08:15:53.537227663 -0400
+++ /home/bmg/build/glibcs/powerpc-linux-gnuspe/glibc/libc.symlist	2018-07-12 08:07:33.724774593 -0400
@@ -1995,0 +1996,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F
Florian Weimer July 12, 2018, 4:46 p.m. UTC | #9
On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

> diff --git a/include/stdc-predef.h b/include/stdc-predef.h

> index c569759..c2ab78a 100644

> --- a/include/stdc-predef.h

> +++ b/include/stdc-predef.h

> @@ -57,7 +57,4 @@

>      - 3 additional Zanabazar Square characters */

>   #define __STDC_ISO_10646__		201706L

>   

> -/* We do not support C11 <threads.h>.  */

> -#define __STDC_NO_THREADS__		1


Should we do this only if we know that the compiler has _Thread_local 
support (based on a GCC and __cplusplus version check)?

> diff --git a/nptl/descr.h b/nptl/descr.h

> index 64ba29e..f00e2c0 100644

> --- a/nptl/descr.h

> +++ b/nptl/descr.h

> @@ -371,6 +371,8 @@ struct pthread

>        to the function.  */

>     void *(*start_routine) (void *);

>     void *arg;

> +  /* Indicates whether is a C11 thread created by thrd_creat.  */

> +  bool c11;

>   

>     /* Debug state.  */

>     td_eventbuf_t eventbuf;


Can you move the new member towards the end of the struct?  I'm worried 
about the ABI implications.

> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c

> index caaf07c..74e773a 100644

> --- a/nptl/pthread_create.c

> +++ b/nptl/pthread_create.c

> @@ -460,7 +460,19 @@ START_THREAD_DEFN

>         LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);

>   

>         /* Run the code the user provided.  */

> -      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));

> +      void *ret;

> +      if (pd->c11)

> +	{

> +	  /* The function pointer of the c11 thread start is cast to an incorrect

> +	     type on __pthread_create_2_1 call, however it is casted back to correct

> +	     one so the call behavior is well-defined (it is assumed that pointers

> +	     to void are able to represent all values of int.  */

> +	  int (*start)(void*) = (int (*) (void*)) pd->start_routine;

> +	  ret = (void*) (intptr_t) start (pd->arg);


(I think this required on m68k, where void * and int are returned in 
different registers.)

> +int

> +thrd_join (thrd_t thr, int *res)

> +{

> +  void *pthread_res;

> +  int err_code = __pthread_join (thr, &pthread_res);

> +  if (res)

> +   *res = (int)((uintptr_t) pthread_res);

> +

> +  return thrd_err_map (err_code);

> +}


Slight inconsistency with intptr_t above.

> diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h

> new file mode 100644

> index 0000000..6adcac4

> --- /dev/null

> +++ b/sysdeps/nptl/threads.h


Should this be nptl/threads.h, not sysdeps/nptl/threads.h?

Thanks,
Florian
Adhemerval Zanella Netto July 12, 2018, 5:38 p.m. UTC | #10
On 12/07/2018 09:18, Florian Weimer wrote:
> On 07/11/2018 06:24 PM, Adhemerval Zanella wrote:

>>

>>

>> On 11/07/2018 12:49, Szabolcs Nagy wrote:

>>> On 10/07/18 20:26, Adhemerval Zanella wrote:

>>>>

>>>>

>>>> On 06/07/2018 09:46, Florian Weimer wrote:

>>>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>>>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>>>>>                   pthread_mutex_getprioceiling \

>>>>>>                   pthread_mutex_setprioceiling \

>>>>>>                   pthread_setname pthread_getname \

>>>>>> -              pthread_setattr_default_np pthread_getattr_default_np

>>>>>> +              pthread_setattr_default_np pthread_getattr_default_np \

>>>>>> +              thrd_create thrd_current thrd_detach thrd_equal \

>>>>>

>>>>> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

>>>>>

>>>>> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.

>>>>

>>>> Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and

>>>> thrd_yield) to libc on my personal branch [1] (the change is just to move

>>>> the objects from libpthread-routines to routines rule in nptl/Makefile).

>>>> I also adjusted the abilist patch with the change.

>>>>

>>>

>>> the abilist patch seems to add

>>> sysdeps/unix/sysv/linux/tile/tilegx64/libpthread.abilist

>>> i think you can drop that (and update the ChangeLog).

>>

>> Thanks for catching this up, I fixed on my personal c11 thread branch.

> 

> I still see the attached ABI diffs.


Thanks, I have corrected them in my personal branch, along with the ChangeLog
entry and a lingering file from tile.

> 

> There is also a new linknamespace failure on hppa:

> 

> [initial] thrd_create -> [libpthread.a(thrd_create.o)] __pthread_create_2_1 -> [libpthread.a(pthread_create.o)] mprotect

> 

> That should be easy to fix.  I'll post a separate patch for that.


You seemed to already fix, thanks.
Adhemerval Zanella Netto July 12, 2018, 5:52 p.m. UTC | #11
On 12/07/2018 13:46, Florian Weimer wrote:
> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

> 

>> diff --git a/include/stdc-predef.h b/include/stdc-predef.h

>> index c569759..c2ab78a 100644

>> --- a/include/stdc-predef.h

>> +++ b/include/stdc-predef.h

>> @@ -57,7 +57,4 @@

>>      - 3 additional Zanabazar Square characters */

>>   #define __STDC_ISO_10646__        201706L

>>   -/* We do not support C11 <threads.h>.  */

>> -#define __STDC_NO_THREADS__        1

> 

> Should we do this only if we know that the compiler has _Thread_local support (based on a GCC and __cplusplus version check)?


It seems reasonable, since its a installed header.  Do we need to 
check for __cplusplus too? Shouldn't __GNUC_PREREQ (4.9) be suffice?

> 

>> diff --git a/nptl/descr.h b/nptl/descr.h

>> index 64ba29e..f00e2c0 100644

>> --- a/nptl/descr.h

>> +++ b/nptl/descr.h

>> @@ -371,6 +371,8 @@ struct pthread

>>        to the function.  */

>>     void *(*start_routine) (void *);

>>     void *arg;

>> +  /* Indicates whether is a C11 thread created by thrd_creat.  */

>> +  bool c11;

>>       /* Debug state.  */

>>     td_eventbuf_t eventbuf;

> 

> Can you move the new member towards the end of the struct?  I'm worried about the ABI implications.


Right, I will do it.

> 

>> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c

>> index caaf07c..74e773a 100644

>> --- a/nptl/pthread_create.c

>> +++ b/nptl/pthread_create.c

>> @@ -460,7 +460,19 @@ START_THREAD_DEFN

>>         LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);

>>           /* Run the code the user provided.  */

>> -      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));

>> +      void *ret;

>> +      if (pd->c11)

>> +    {

>> +      /* The function pointer of the c11 thread start is cast to an incorrect

>> +         type on __pthread_create_2_1 call, however it is casted back to correct

>> +         one so the call behavior is well-defined (it is assumed that pointers

>> +         to void are able to represent all values of int.  */

>> +      int (*start)(void*) = (int (*) (void*)) pd->start_routine;

>> +      ret = (void*) (intptr_t) start (pd->arg);

> 

> (I think this required on m68k, where void * and int are returned in different registers.)

> 

>> +int

>> +thrd_join (thrd_t thr, int *res)

>> +{

>> +  void *pthread_res;

>> +  int err_code = __pthread_join (thr, &pthread_res);

>> +  if (res)

>> +   *res = (int)((uintptr_t) pthread_res);

>> +

>> +  return thrd_err_map (err_code);

>> +}

> 

> Slight inconsistency with intptr_t above.


Indeed, it seems there is no need to cast.

> 

>> diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h

>> new file mode 100644

>> index 0000000..6adcac4

>> --- /dev/null

>> +++ b/sysdeps/nptl/threads.h

> 

> Should this be nptl/threads.h, not sysdeps/nptl/threads.h?


Right, I will move it.
Florian Weimer July 12, 2018, 6:24 p.m. UTC | #12
On 07/12/2018 07:52 PM, Adhemerval Zanella wrote:
> 

> 

> On 12/07/2018 13:46, Florian Weimer wrote:

>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>

>>> diff --git a/include/stdc-predef.h b/include/stdc-predef.h

>>> index c569759..c2ab78a 100644

>>> --- a/include/stdc-predef.h

>>> +++ b/include/stdc-predef.h

>>> @@ -57,7 +57,4 @@

>>>       - 3 additional Zanabazar Square characters */

>>>    #define __STDC_ISO_10646__        201706L

>>>    -/* We do not support C11 <threads.h>.  */

>>> -#define __STDC_NO_THREADS__        1

>>

>> Should we do this only if we know that the compiler has _Thread_local support (based on a GCC and __cplusplus version check)?

> 

> It seems reasonable, since its a installed header.  Do we need to

> check for __cplusplus too? Shouldn't __GNUC_PREREQ (4.9) be suffice?


I think we can use __thread instead of _Thread_local with even older 
compilers, and also factor in __cplusplus if it is recent enough 
(essentially 2011 and later) for the !__GNUC__ case.

Maybe it's sufficient to say

#if !defined (__GNUC__) && !defined (__cpluscplus) \
   &&  __cplusplus < 201103L)
# define __STDC_NO_THREADS__        1
#endif

On the other hand, maybe your original change is right because in C11, 
_Thread_local support is not optional.  Implementations are required to 
recognize the keyword (and presumably ignore it) even if they define 
__STDC_NO_THREADS__.  And our <threads.h> will generally work fine even 
if the compiler does not actually support _Thread_local.  So I'd say go 
with your original change.

(But I do think you need to do something about thread_local in the C++ 
case, independently of this discussion.)

Thanks,
Florian
Adhemerval Zanella Netto July 12, 2018, 7:19 p.m. UTC | #13
On 12/07/2018 15:24, Florian Weimer wrote:
> On 07/12/2018 07:52 PM, Adhemerval Zanella wrote:

>>

>>

>> On 12/07/2018 13:46, Florian Weimer wrote:

>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>

>>>> diff --git a/include/stdc-predef.h b/include/stdc-predef.h

>>>> index c569759..c2ab78a 100644

>>>> --- a/include/stdc-predef.h

>>>> +++ b/include/stdc-predef.h

>>>> @@ -57,7 +57,4 @@

>>>>       - 3 additional Zanabazar Square characters */

>>>>    #define __STDC_ISO_10646__        201706L

>>>>    -/* We do not support C11 <threads.h>.  */

>>>> -#define __STDC_NO_THREADS__        1

>>>

>>> Should we do this only if we know that the compiler has _Thread_local support (based on a GCC and __cplusplus version check)?

>>

>> It seems reasonable, since its a installed header.  Do we need to

>> check for __cplusplus too? Shouldn't __GNUC_PREREQ (4.9) be suffice?

> 

> I think we can use __thread instead of _Thread_local with even older compilers, and also factor in __cplusplus if it is recent enough (essentially 2011 and later) for the !__GNUC__ case.

> 

> Maybe it's sufficient to say

> 

> #if !defined (__GNUC__) && !defined (__cpluscplus) \

>   &&  __cplusplus < 201103L)

> # define __STDC_NO_THREADS__        1

> #endif

> 

> On the other hand, maybe your original change is right because in C11, _Thread_local support is not optional.  Implementations are required to recognize the keyword (and presumably ignore it) even if they define __STDC_NO_THREADS__.  And our <threads.h> will generally work fine even if the compiler does not actually support _Thread_local.  So I'd say go with your original change.

> 

> (But I do think you need to do something about thread_local in the C++ case, independently of this discussion.)


Also on GCC BZ#53769 [1] Joseph wrote that check for __STDC_VERSION__
and/or __STDC_NO_THREADS__ is not meaningful to documented incomplete
compiler support for language standard.  This is at least for GCC 
standpoint, not sure about other compilers.

We could add a check like:

#if (defined (__GNUC__) && !__GNUC_PREREQ (4.9))
    || (!defined (__cpluscplus) &&  __cplusplus < 201103L)
#  define __STDC_NO_THREADS__   1
#endif

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
Florian Weimer July 12, 2018, 7:26 p.m. UTC | #14
On 07/12/2018 09:19 PM, Adhemerval Zanella wrote:
> Also on GCC BZ#53769 [1] Joseph wrote that check for __STDC_VERSION__

> and/or __STDC_NO_THREADS__ is not meaningful to documented incomplete

> compiler support for language standard.  This is at least for GCC

> standpoint, not sure about other compilers.

> 

> We could add a check like:

> 

> #if (defined (__GNUC__) && !__GNUC_PREREQ (4.9))

>      || (!defined (__cpluscplus) &&  __cplusplus < 201103L)

> #  define __STDC_NO_THREADS__   1

> #endif

> 

> [1]https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769


I think your first patch was fine.  The <threads.h> header exists after 
your change.

We could polish the definition of thread_local in the header file with 
some conditionals, though, so that we fall back to __thread for GCC 
prior to 4.9.  The definition of the thread_local macro will be 
non-confirming, but that's what you get for using a non-conforming 
implementation.

(If the C compiler is not known to be C, we need to use _Thread_local, 
even though __thread probably covers more old implementations out there.)

Thanks,
Florian
Adhemerval Zanella Netto July 12, 2018, 7:32 p.m. UTC | #15
On 12/07/2018 14:52, Adhemerval Zanella wrote:
> 

> 

> On 12/07/2018 13:46, Florian Weimer wrote:

>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>> +int

>>> +thrd_join (thrd_t thr, int *res)

>>> +{

>>> +  void *pthread_res;

>>> +  int err_code = __pthread_join (thr, &pthread_res);

>>> +  if (res)

>>> +   *res = (int)((uintptr_t) pthread_res);

>>> +

>>> +  return thrd_err_map (err_code);

>>> +}

>>

>> Slight inconsistency with intptr_t above.

> 

> Indeed, it seems there is no need to cast.


In fact the cast this construction is still required, since the pthread_join
returned value might have a different size of the expected c11 thrd_join.

As a slight optimization I changed to 

  int err_code = __pthread_timedjoin_ex (thr, &pthread_res, NULL, true);

(it should avoid calling pthread_join which will in turn call
pthread_timedjoin_ex).
Florian Weimer July 12, 2018, 7:35 p.m. UTC | #16
On 07/12/2018 09:32 PM, Adhemerval Zanella wrote:
> 

> 

> On 12/07/2018 14:52, Adhemerval Zanella wrote:

>>

>>

>> On 12/07/2018 13:46, Florian Weimer wrote:

>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>> +int

>>>> +thrd_join (thrd_t thr, int *res)

>>>> +{

>>>> +  void *pthread_res;

>>>> +  int err_code = __pthread_join (thr, &pthread_res);

>>>> +  if (res)

>>>> +   *res = (int)((uintptr_t) pthread_res);

>>>> +

>>>> +  return thrd_err_map (err_code);

>>>> +}

>>>

>>> Slight inconsistency with intptr_t above.

>>

>> Indeed, it seems there is no need to cast.

> 

> In fact the cast this construction is still required, since the pthread_join

> returned value might have a different size of the expected c11 thrd_join.


I meant the inconsistency between intptr_t and uintptr_t.

Florian
Adhemerval Zanella Netto July 12, 2018, 7:41 p.m. UTC | #17
On 12/07/2018 16:26, Florian Weimer wrote:
> On 07/12/2018 09:19 PM, Adhemerval Zanella wrote:

>> Also on GCC BZ#53769 [1] Joseph wrote that check for __STDC_VERSION__

>> and/or __STDC_NO_THREADS__ is not meaningful to documented incomplete

>> compiler support for language standard.  This is at least for GCC

>> standpoint, not sure about other compilers.

>>

>> We could add a check like:

>>

>> #if (defined (__GNUC__) && !__GNUC_PREREQ (4.9))

>>      || (!defined (__cpluscplus) &&  __cplusplus < 201103L)

>> #  define __STDC_NO_THREADS__   1

>> #endif

>>

>> [1]https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769

> 

> I think your first patch was fine.  The <threads.h> header exists after your change.

> 

> We could polish the definition of thread_local in the header file with some conditionals, though, so that we fall back to __thread for GCC prior to 4.9.  The definition of the thread_local macro will be non-confirming, but that's what you get for using a non-conforming implementation.

> 

> (If the C compiler is not known to be C, we need to use _Thread_local, even though __thread probably covers more old implementations out there.)

> 

> Thanks,

> Florian


Right, I will keep the definition as is then.
Adhemerval Zanella Netto July 12, 2018, 7:43 p.m. UTC | #18
On 12/07/2018 16:35, Florian Weimer wrote:
> On 07/12/2018 09:32 PM, Adhemerval Zanella wrote:

>>

>>

>> On 12/07/2018 14:52, Adhemerval Zanella wrote:

>>>

>>>

>>> On 12/07/2018 13:46, Florian Weimer wrote:

>>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>>> +int

>>>>> +thrd_join (thrd_t thr, int *res)

>>>>> +{

>>>>> +  void *pthread_res;

>>>>> +  int err_code = __pthread_join (thr, &pthread_res);

>>>>> +  if (res)

>>>>> +   *res = (int)((uintptr_t) pthread_res);

>>>>> +

>>>>> +  return thrd_err_map (err_code);

>>>>> +}

>>>>

>>>> Slight inconsistency with intptr_t above.

>>>

>>> Indeed, it seems there is no need to cast.

>>

>> In fact the cast this construction is still required, since the pthread_join

>> returned value might have a different size of the expected c11 thrd_join.

> 

> I meant the inconsistency between intptr_t and uintptr_t.


Ah right, there is no requirement to use a signed cast on pthread_create.
I will change it to uintptr_t.
Florian Weimer July 13, 2018, 7:03 a.m. UTC | #19
On 07/12/2018 07:38 PM, Adhemerval Zanella wrote:
> 

> 

> On 12/07/2018 09:18, Florian Weimer wrote:

>> On 07/11/2018 06:24 PM, Adhemerval Zanella wrote:

>>>

>>>

>>> On 11/07/2018 12:49, Szabolcs Nagy wrote:

>>>> On 10/07/18 20:26, Adhemerval Zanella wrote:

>>>>>

>>>>>

>>>>> On 06/07/2018 09:46, Florian Weimer wrote:

>>>>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>>>>> @@ -139,7 +139,9 @@ libpthread-routines = nptl-init vars events version pt-interp \

>>>>>>>                    pthread_mutex_getprioceiling \

>>>>>>>                    pthread_mutex_setprioceiling \

>>>>>>>                    pthread_setname pthread_getname \

>>>>>>> -              pthread_setattr_default_np pthread_getattr_default_np

>>>>>>> +              pthread_setattr_default_np pthread_getattr_default_np \

>>>>>>> +              thrd_create thrd_current thrd_detach thrd_equal \

>>>>>>

>>>>>> thrd_current should live in libc, not in libpthread.  Same for thrd_equal, I suppose.  You should just duplicate the comparison, seeing that we haven't done that particular cleanup for pthread_equal yet.

>>>>>>

>>>>>> Not sure about thrd_sleep and thrd_yield, but I lean towards libc there as well.

>>>>>

>>>>> Right, I added all four symbols (thrd_current, thrd_equal, thrd_sleep, and

>>>>> thrd_yield) to libc on my personal branch [1] (the change is just to move

>>>>> the objects from libpthread-routines to routines rule in nptl/Makefile).

>>>>> I also adjusted the abilist patch with the change.

>>>>>

>>>>

>>>> the abilist patch seems to add

>>>> sysdeps/unix/sysv/linux/tile/tilegx64/libpthread.abilist

>>>> i think you can drop that (and update the ChangeLog).

>>>

>>> Thanks for catching this up, I fixed on my personal c11 thread branch.

>>

>> I still see the attached ABI diffs.

> 

> Thanks, I have corrected them in my personal branch, along with the ChangeLog

> entry and a lingering file from tile.


As of commit 2b9d7c41ade511d99cd917bb8d28eb0fe91971ed, I still see:

==> 
/home/bmg/build/glibcs/mipsel-linux-gnu-nan2008-soft/glibc/elf/check-abi-libc.out 
<==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist 
2018-07-10 08:15:53.536227638 -0400
+++ 
/home/bmg/build/glibcs/mipsel-linux-gnu-nan2008-soft/glibc/libc.symlist 
    2018-07-13 03:00:06.345221784 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> 
/home/bmg/build/glibcs/mipsel-linux-gnu-soft/glibc/elf/check-abi-libc.out 
<==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist 
2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mipsel-linux-gnu-soft/glibc/libc.symlist 
2018-07-13 02:58:41.692589329 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> 
/home/bmg/build/glibcs/mips-linux-gnu-nan2008-soft/glibc/elf/check-abi-libc.out 
<==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist 
2018-07-10 08:15:53.536227638 -0400
+++ 
/home/bmg/build/glibcs/mips-linux-gnu-nan2008-soft/glibc/libc.symlist 
    2018-07-13 03:00:43.831389053 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

==> 
/home/bmg/build/glibcs/mips-linux-gnu-soft/glibc/elf/check-abi-libc.out <==
--- ../sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist 
2018-07-10 08:15:53.536227638 -0400
+++ /home/bmg/build/glibcs/mips-linux-gnu-soft/glibc/libc.symlist 
2018-07-13 03:00:32.210027180 -0400
@@ -1963,0 +1964,4 @@ GLIBC_2.28 statx F
+GLIBC_2.28 thrd_current F
+GLIBC_2.28 thrd_equal F
+GLIBC_2.28 thrd_sleep F
+GLIBC_2.28 thrd_yield F

Florian
Florian Weimer July 13, 2018, 9:45 a.m. UTC | #20
On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:
>    2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering

>       errno, to handle expected standard return codes, and to avoid making

>       the call a POSIX cancellation entrypoint.


Isn't this inconsistent with the conditional variable wait and thread 
join functions, which are still cancellation points?

On the other hand, a sleep function which is not a cancellation point 
may be useful.

Thanks,
Florian
Florian Weimer July 13, 2018, 9:48 a.m. UTC | #21
On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:
> +/* Exit and error codes.  */

> +enum

> +{

> +  thrd_success  = 0,

> +  thrd_busy     = 1,

> +  thrd_error    = 2,

> +  thrd_nomem    = 3,

> +  thrd_timedout = 4

> +};


We could make the mapping more efficient if we used EBUSY, EINVAL, 
ENOMEM, ETIMEDOUT for the error codes, possibly with the help of a .sym 
file.  I expect that this would allow us to eliminate some of the 
wrappers and use symbol aliases instead, but it doesn't look like there 
would be many such cases.  Your call.

Thanks,
Florian
Adhemerval Zanella Netto July 13, 2018, 12:59 p.m. UTC | #22
On 13/07/2018 06:45, Florian Weimer wrote:
> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>    2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering

>>       errno, to handle expected standard return codes, and to avoid making

>>       the call a POSIX cancellation entrypoint.

> 

> Isn't this inconsistent with the conditional variable wait and thread join functions, which are still cancellation points?

> 

> On the other hand, a sleep function which is not a cancellation point may be useful.


I am not sure which would be the best option to handle POSIX cancellation
with C11 threads with nptl implementation. Most straightforward option is
just use cancellation entrypoints as default, even though using thread
cancellation in C11 is UB (there is no defined way the use can get the
POSIX thread id from a C11 thread). This don't require much internal
code change

Another option is just disable cancellation by using non-cancellable
entry-points and/or explicit disable cancellation.  For thrd_join is
just a matter to set on '__pthread_timedjoin_ex', but for 
cnd_wait/cnd_timedwait we either need to explicit enable/disable or 
add an option to __pthread_cond_wait_common to select whether to use
cancellable syscalls.
Florian Weimer July 13, 2018, 1:04 p.m. UTC | #23
On 07/13/2018 02:59 PM, Adhemerval Zanella wrote:
> 

> 

> On 13/07/2018 06:45, Florian Weimer wrote:

>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>     2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering

>>>        errno, to handle expected standard return codes, and to avoid making

>>>        the call a POSIX cancellation entrypoint.

>>

>> Isn't this inconsistent with the conditional variable wait and thread join functions, which are still cancellation points?

>>

>> On the other hand, a sleep function which is not a cancellation point may be useful.

> 

> I am not sure which would be the best option to handle POSIX cancellation

> with C11 threads with nptl implementation. Most straightforward option is

> just use cancellation entrypoints as default, even though using thread

> cancellation in C11 is UB (there is no defined way the use can get the

> POSIX thread id from a C11 thread).


That's not true.  The POSIX thread ID is available using pthread_self on 
the thread itself, and that can be passed to another thread.

> Another option is just disable cancellation by using non-cancellable

> entry-points and/or explicit disable cancellation.  For thrd_join is

> just a matter to set on '__pthread_timedjoin_ex', but for

> cnd_wait/cnd_timedwait we either need to explicit enable/disable or

> add an option to __pthread_cond_wait_common to select whether to use

> cancellable syscalls.


 From my point of view, the least surprising approach would be to make 
thrd_sleep a cancellation point to match nanosleep.

Thanks,
Florian
Adhemerval Zanella Netto July 13, 2018, 1:18 p.m. UTC | #24
On 13/07/2018 10:04, Florian Weimer wrote:
> On 07/13/2018 02:59 PM, Adhemerval Zanella wrote:

>>

>>

>> On 13/07/2018 06:45, Florian Weimer wrote:

>>> On 02/02/2018 06:04 PM, Adhemerval Zanella wrote:

>>>>     2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering

>>>>        errno, to handle expected standard return codes, and to avoid making

>>>>        the call a POSIX cancellation entrypoint.

>>>

>>> Isn't this inconsistent with the conditional variable wait and thread join functions, which are still cancellation points?

>>>

>>> On the other hand, a sleep function which is not a cancellation point may be useful.

>>

>> I am not sure which would be the best option to handle POSIX cancellation

>> with C11 threads with nptl implementation. Most straightforward option is

>> just use cancellation entrypoints as default, even though using thread

>> cancellation in C11 is UB (there is no defined way the use can get the

>> POSIX thread id from a C11 thread).

> 

> That's not true.  The POSIX thread ID is available using pthread_self on the thread itself, and that can be passed to another thread.


That is what I am not sure, if mixing POSIX semantic with C11 is really
defined by any standard (for instance, calling pthread_cancel with an
POSIX thread ID which was not created by pthread_create).

> 

>> Another option is just disable cancellation by using non-cancellable

>> entry-points and/or explicit disable cancellation.  For thrd_join is

>> just a matter to set on '__pthread_timedjoin_ex', but for

>> cnd_wait/cnd_timedwait we either need to explicit enable/disable or

>> add an option to __pthread_cond_wait_common to select whether to use

>> cancellable syscalls.

> 

> From my point of view, the least surprising approach would be to make thrd_sleep a cancellation point to match nanosleep.


Right, I will change thrd_sleep to use a cancellation entrypoint. We
can evaluate the POSIX cancellation interaction with C11 threads in
next releases.
Florian Weimer July 13, 2018, 1:21 p.m. UTC | #25
On 07/13/2018 03:18 PM, Adhemerval Zanella wrote:
> Right, I will change thrd_sleep to use a cancellation entrypoint. We

> can evaluate the POSIX cancellation interaction with C11 threads in

> next releases.


Agreed.  We've discussed internally a POSIX thread attribute which 
inhibits cancellation for thread in case it is created by a higher-level 
run-time which does not support cancellation.  I'm not sure if this 
should apply to C11 threads, but we should consider it as an enhancement 
for POSIX threads at least.

Thanks,
Florian
Andreas Schwab July 25, 2018, 7:20 a.m. UTC | #26
On Feb 02 2018, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> @@ -197,7 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) \

>  			 $(common-objpfx)crypt/libcrypt.a

>  linknamespace-libs-ISO = $(linknamespace-libs-isoc)

>  linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)

> -linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)

> +linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \

> +			   $(common-objpfx)nptl/libpthread.a

>  linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \

>  			  $(common-objpfx)crypt/libcrypt.a


You have reverted commit e69d994a63, which breaks --disable-crypt
builds.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
Florian Weimer July 25, 2018, 7:38 a.m. UTC | #27
On 07/25/2018 09:20 AM, Andreas Schwab wrote:
> On Feb 02 2018, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

>> @@ -197,7 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) \

>>   			 $(common-objpfx)crypt/libcrypt.a

>>   linknamespace-libs-ISO = $(linknamespace-libs-isoc)

>>   linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)

>> -linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)

>> +linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \

>> +			   $(common-objpfx)nptl/libpthread.a

>>   linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \

>>   			  $(common-objpfx)crypt/libcrypt.a

> 

> You have reverted commit e69d994a63, which breaks --disable-crypt

> builds.


Oh.  So we need this fix?

Thanks,
Florian
Subject: [PATCH] conform: Do not add libcrypt twice in linknamespace tests
To: libc-alpha@sourceware.org

2018-07-25  Florian Weimer  <fweimer@redhat.com>

	* conform/Makefile (linknamespace-libs-XPG4): Do not add libcrypt
	twice.

diff --git a/conform/Makefile b/conform/Makefile
index a0ab70e302..98a9f8ea3e 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -198,8 +198,7 @@ linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \
 			   $(common-objpfx)nptl/libpthread.a
-linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
-			  $(common-objpfx)crypt/libcrypt.a
+linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
 linknamespace-libs-POSIX = $(linknamespace-libs-thr)
 linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
Joseph Myers July 25, 2018, 10:29 a.m. UTC | #28
On Wed, 25 Jul 2018, Andreas Schwab wrote:

> On Feb 02 2018, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

> > @@ -197,7 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) \

> >  			 $(common-objpfx)crypt/libcrypt.a

> >  linknamespace-libs-ISO = $(linknamespace-libs-isoc)

> >  linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)

> > -linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)

> > +linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \

> > +			   $(common-objpfx)nptl/libpthread.a

> >  linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \

> >  			  $(common-objpfx)crypt/libcrypt.a

> 

> You have reverted commit e69d994a63, which breaks --disable-crypt

> builds.


Also, the hardcoded reference to $(common-objpfx)nptl/libpthread.a should 
be $(static-thread-library).  As-is, the patch has broken the testsuite 
build for Hurd (not just introduced the expected failures from lack of 
support for C11 threads in HTL).

-- 
Joseph S. Myers
joseph@codesourcery.com
diff mbox series

Patch

diff --git a/conform/Makefile b/conform/Makefile
index 864fdec..82248ab 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -34,9 +34,9 @@  conformtest-headers-ISO := assert.h ctype.h errno.h float.h limits.h locale.h \
 conformtest-headers-ISO99 := $(conformtest-headers-ISO) complex.h fenv.h \
 			     inttypes.h iso646.h stdbool.h stdint.h tgmath.h \
 			     wchar.h wctype.h
-# Missing ISO11 expectations for: stdatomic.h threads.h.
+# Missing ISO11 expectations for: stdatomic.h
 conformtest-headers-ISO11 := $(conformtest-headers-ISO99) stdalign.h \
-			     stdnoreturn.h uchar.h
+			     stdnoreturn.h threads.h uchar.h
 conformtest-headers-POSIX := $(conformtest-headers-ISO) aio.h dirent.h \
 			     fcntl.h fnmatch.h glob.h grp.h mqueue.h \
 			     pthread.h pwd.h regex.h sched.h semaphore.h \
@@ -197,7 +197,8 @@  linknamespace-libs-xsi = $(linknamespace-libs-posix) \
 			 $(common-objpfx)crypt/libcrypt.a
 linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
-linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)
+linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \
+			   $(common-objpfx)nptl/libpthread.a
 linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
 			  $(common-objpfx)crypt/libcrypt.a
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
diff --git a/conform/data/threads.h-data b/conform/data/threads.h-data
new file mode 100644
index 0000000..bc2d857
--- /dev/null
+++ b/conform/data/threads.h-data
@@ -0,0 +1,23 @@ 
+#if defined ISO11
+
+constant thrd_success
+constant thrd_busy
+constant thrd_error
+constant thrd_nomem
+constant thrd_timedout
+
+type thrd_t
+type thrd_start_t
+
+function int thrd_create (thrd_t*, thrd_start_t, void*)
+function int thrd_equal (thrd_t, thrd_t)
+function thrd_t thrd_current (void)
+function int thrd_sleep (const struct timespec*, struct timespec*)
+function void thrd_exit (int)
+function int thrd_detach (thrd_t)
+function int thrd_join (thrd_t, int*)
+function void thrd_yield (void)
+
+#include "time.h-data"
+
+#endif
diff --git a/include/stdc-predef.h b/include/stdc-predef.h
index c569759..c2ab78a 100644
--- a/include/stdc-predef.h
+++ b/include/stdc-predef.h
@@ -57,7 +57,4 @@ 
    - 3 additional Zanabazar Square characters */
 #define __STDC_ISO_10646__		201706L
 
-/* We do not support C11 <threads.h>.  */
-#define __STDC_NO_THREADS__		1
-
 #endif
diff --git a/nptl/Makefile b/nptl/Makefile
index 6fc2c8b..a853c46 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -22,7 +22,7 @@  subdir	:= nptl
 
 include ../Makeconfig
 
-headers := pthread.h semaphore.h bits/semaphore.h
+headers := pthread.h semaphore.h bits/semaphore.h threads.h
 
 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
@@ -139,7 +139,9 @@  libpthread-routines = nptl-init vars events version pt-interp \
 		      pthread_mutex_getprioceiling \
 		      pthread_mutex_setprioceiling \
 		      pthread_setname pthread_getname \
-		      pthread_setattr_default_np pthread_getattr_default_np
+		      pthread_setattr_default_np pthread_getattr_default_np \
+		      thrd_create thrd_current thrd_detach thrd_equal \
+		      thrd_exit thrd_join thrd_sleep thrd_yield
 #		      pthread_setuid pthread_seteuid pthread_setreuid \
 #		      pthread_setresuid \
 #		      pthread_setgid pthread_setegid pthread_setregid \
diff --git a/nptl/Versions b/nptl/Versions
index 0ae5def..4905c84 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -265,6 +265,12 @@  libpthread {
   GLIBC_2.22 {
   }
 
+  # C11 thread symbols.
+  GLIBC_2.28 {
+    thrd_create; thrd_current; thrd_detach; thrd_equal; thrd_exit; thrd_join;
+    thrd_sleep; thrd_yield;
+  }
+
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
     __pthread_clock_gettime; __pthread_clock_settime;
diff --git a/nptl/descr.h b/nptl/descr.h
index 64ba29e..f00e2c0 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -371,6 +371,8 @@  struct pthread
      to the function.  */
   void *(*start_routine) (void *);
   void *arg;
+  /* Indicates whether is a C11 thread created by thrd_creat.  */
+  bool c11;
 
   /* Debug state.  */
   td_eventbuf_t eventbuf;
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 583515f..83b730c 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -173,6 +173,9 @@  enum
 #define __PTHREAD_ONCE_DONE		2
 #define __PTHREAD_ONCE_FORK_GEN_INCR	4
 
+/* Attribute to indicate thread creation was issued from C11 thrd_create.  */
+#define ATTR_C11_THREAD ((void*)(uintptr_t)-1)
+
 
 /* Condition variable definitions.  See __pthread_cond_wait_common.
    Need to be defined here so there is one place from which
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index caaf07c..74e773a 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -460,7 +460,19 @@  START_THREAD_DEFN
       LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
 
       /* Run the code the user provided.  */
-      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
+      void *ret;
+      if (pd->c11)
+	{
+	  /* The function pointer of the c11 thread start is cast to an incorrect
+	     type on __pthread_create_2_1 call, however it is casted back to correct
+	     one so the call behavior is well-defined (it is assumed that pointers
+	     to void are able to represent all values of int.  */
+	  int (*start)(void*) = (int (*) (void*)) pd->start_routine;
+	  ret = (void*) (intptr_t) start (pd->arg);
+	}
+      else
+	ret = pd->start_routine (pd->arg);
+      THREAD_SETMEM (pd, result, ret);
     }
 
   /* Call destructors for the thread_local TLS variables.  */
@@ -613,7 +625,8 @@  __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
   const struct pthread_attr *iattr = (struct pthread_attr *) attr;
   struct pthread_attr default_attr;
   bool free_cpuset = false;
-  if (iattr == NULL)
+  bool c11 = (attr == ATTR_C11_THREAD);
+  if (iattr == NULL || c11)
     {
       lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
       default_attr = __default_pthread_attr;
@@ -671,6 +684,7 @@  __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
      get the information from its thread descriptor.  */
   pd->start_routine = start_routine;
   pd->arg = arg;
+  pd->c11 = c11;
 
   /* Copy the thread attribute flags.  */
   struct pthread *self = THREAD_SELF;
diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
new file mode 100644
index 0000000..d39034c
--- /dev/null
+++ b/nptl/thrd_create.c
@@ -0,0 +1,29 @@ 
+/* C11 threads thread creation implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
+{
+  _Static_assert (sizeof (thr) == sizeof (pthread_t), "thrd_t size");
+
+  int err_code = __pthread_create_2_1 (thr, ATTR_C11_THREAD,
+				       (void* (*) (void*))func, arg);
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/thrd_current.c b/nptl/thrd_current.c
new file mode 100644
index 0000000..a1c73b2
--- /dev/null
+++ b/nptl/thrd_current.c
@@ -0,0 +1,25 @@ 
+/* C11 threads current thread implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+thrd_t
+thrd_current (void)
+{
+  return (thrd_t) THREAD_SELF;
+}
diff --git a/nptl/thrd_detach.c b/nptl/thrd_detach.c
new file mode 100644
index 0000000..be2c3e1
--- /dev/null
+++ b/nptl/thrd_detach.c
@@ -0,0 +1,28 @@ 
+/* C11 threads thread detach implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+thrd_detach (thrd_t thr)
+{
+  int err_code;
+
+  err_code = __pthread_detach (thr);
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/thrd_equal.c b/nptl/thrd_equal.c
new file mode 100644
index 0000000..951ab40
--- /dev/null
+++ b/nptl/thrd_equal.c
@@ -0,0 +1,25 @@ 
+/* C11 threads thread equality check implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+thrd_equal (thrd_t lhs, thrd_t rhs)
+{
+  return __pthread_equal (lhs, rhs);
+}
diff --git a/nptl/thrd_exit.c b/nptl/thrd_exit.c
new file mode 100644
index 0000000..6b37774
--- /dev/null
+++ b/nptl/thrd_exit.c
@@ -0,0 +1,25 @@ 
+/* C11 threads thread exit implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+_Noreturn void
+thrd_exit (int res)
+{
+  __pthread_exit ((void*)(uintptr_t) res);
+}
diff --git a/nptl/thrd_join.c b/nptl/thrd_join.c
new file mode 100644
index 0000000..d3dbcdb
--- /dev/null
+++ b/nptl/thrd_join.c
@@ -0,0 +1,30 @@ 
+/* C11 threads thread join implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+thrd_join (thrd_t thr, int *res)
+{
+  void *pthread_res;
+  int err_code = __pthread_join (thr, &pthread_res);
+  if (res)
+   *res = (int)((uintptr_t) pthread_res);
+
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/thrd_priv.h b/nptl/thrd_priv.h
new file mode 100644
index 0000000..97f4102
--- /dev/null
+++ b/nptl/thrd_priv.h
@@ -0,0 +1,45 @@ 
+/* Internal C11 threads definitions.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef THRD_PRIV_H
+# define THRD_PRIV_H
+
+#include <features.h>
+#include <threads.h>
+#include <errno.h>
+#include "pthreadP.h"	/* For pthread_{mutex,cond}_t definitions.  */
+
+static __always_inline int
+thrd_err_map (int err_code)
+{
+  switch (err_code)
+  {
+    case 0:
+      return thrd_success;
+    case ENOMEM:
+      return thrd_nomem;
+    case ETIMEDOUT:
+      return thrd_timedout;
+    case EBUSY:
+      return thrd_busy;
+    default:
+      return thrd_error;
+  }
+}
+
+#endif
diff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c
new file mode 100644
index 0000000..9f5a28f
--- /dev/null
+++ b/nptl/thrd_sleep.c
@@ -0,0 +1,38 @@ 
+/* C11 threads thread sleep implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+#include <time.h>
+
+int
+thrd_sleep (const struct timespec* time_point, struct timespec* remaining)
+{
+  /* It calls the syscalls directly to avoid cancellable version.  */
+  INTERNAL_SYSCALL_DECL (err);
+  int ret = INTERNAL_SYSCALL_CALL (nanosleep, err, time_point, remaining);
+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+    {
+      /* C11 states thrd_sleep function returns -1 if it has been interrupted
+         by a signal, or a negative value if it fails.  */
+      ret = INTERNAL_SYSCALL_ERRNO (ret, err);
+      if (ret == EINTR)
+	return -1;
+      return -2;
+    }
+  return 0;
+}
diff --git a/nptl/thrd_yield.c b/nptl/thrd_yield.c
new file mode 100644
index 0000000..9ebcbae
--- /dev/null
+++ b/nptl/thrd_yield.c
@@ -0,0 +1,26 @@ 
+/* C11 threads thread yield implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+void
+thrd_yield (void)
+{
+  INTERNAL_SYSCALL_DECL (err);
+  INTERNAL_SYSCALL_CALL (sched_yield, err);
+}
diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h
new file mode 100644
index 0000000..6adcac4
--- /dev/null
+++ b/sysdeps/nptl/threads.h
@@ -0,0 +1,90 @@ 
+/* ISO C11 Standard: 7.26 - Thread support library  <threads.h>.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _THREADS_H
+#define _THREADS_H	1
+
+#include <features.h>
+#include <time.h>
+
+__BEGIN_DECLS
+
+#include <bits/types/struct_timespec.h>
+
+typedef unsigned long int thrd_t;
+typedef int (*thrd_start_t) (void*);
+
+/* Exit and error codes.  */
+enum
+{
+  thrd_success  = 0,
+  thrd_busy     = 1,
+  thrd_error    = 2,
+  thrd_nomem    = 3,
+  thrd_timedout = 4
+};
+
+/* Threads functions.  */
+
+/* Create a new thread executing the function __FUNC.  Arguments for __FUNC
+   are passed through __ARG.  If succesful, __THR is set to new thread
+   identifier.  */
+extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg);
+
+/* Check if __LHS and __RHS point to the same thread.  */
+extern int thrd_equal (thrd_t __lhs, thrd_t __rhs);
+
+/* Return current thread identifier.  */
+extern thrd_t thrd_current (void);
+
+/* Block current thread execution for at least the time pointed by
+   __TIME_POINT.  The current thread may resume if receives a signal.  In
+   that case, if __REMAINING is not NULL, the remaining time is stored in
+   the object pointed by it.  */
+extern int thrd_sleep (const struct timespec *__time_point,
+		       struct timespec *__remaining);
+
+/* Terminate current thread execution, cleaning up any thread local
+   storage and freeing resources.  Returns the value specified in __RES.  */
+extern void thrd_exit (int __res) __attribute__ ((__noreturn__));
+
+/* Detach the thread identified by __THR from the current environment
+   (tt does not allow join or wait for it).  */
+extern int thrd_detach (thrd_t __thr);
+
+/* Block current thread until execution of __THR is complete.  In case that
+   __RES is not NULL, will store the return value of __THR when exiting.  */
+extern int thrd_join (thrd_t __thr, int *__res);
+
+/* Stop current thread execution and call the scheduler to decide which
+   thread should execute next.  The current thread may be selected by the
+   scheduler to keep running.  */
+extern void thrd_yield (void);
+
+#ifdef __USE_EXTERN_INLINES
+/* Optimizations.  */
+__extern_inline int
+thrd_equal (thrd_t __thread1, thrd_t __thread2)
+{
+  return __thread1 == __thread2;
+}
+#endif
+
+__END_DECLS
+
+#endif /* _THREADS_H */