{"id":817686,"url":"http://patchwork.ozlabs.org/api/patches/817686/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/patch/1506112024-22601-2-git-send-email-adhemerval.zanella@linaro.org/","project":{"id":41,"url":"http://patchwork.ozlabs.org/api/projects/41/?format=json","name":"GNU C Library","link_name":"glibc","list_id":"libc-alpha.sourceware.org","list_email":"libc-alpha@sourceware.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1506112024-22601-2-git-send-email-adhemerval.zanella@linaro.org>","list_archive_url":null,"date":"2017-09-22T20:26:57","name":"[1/8] nptl: Add C11 threads thrd_* functions","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"3b21502693574e66513be5a58d113b66f02eb3e8","submitter":{"id":66065,"url":"http://patchwork.ozlabs.org/api/people/66065/?format=json","name":"Adhemerval Zanella Netto","email":"adhemerval.zanella@linaro.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/glibc/patch/1506112024-22601-2-git-send-email-adhemerval.zanella@linaro.org/mbox/","series":[{"id":4704,"url":"http://patchwork.ozlabs.org/api/series/4704/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/list/?series=4704","date":"2017-09-22T20:26:56","name":"Add support for ISO C threads.h","version":7,"mbox":"http://patchwork.ozlabs.org/series/4704/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/817686/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/817686/checks/","tags":{},"related":[],"headers":{"Return-Path":"<libc-alpha-return-84874-incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","mailing list libc-alpha@sourceware.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=sourceware.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=libc-alpha-return-84874-incoming=patchwork.ozlabs.org@sourceware.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tsecure) header.d=sourceware.org header.i=@sourceware.org\n\theader.b=\"PxRfNNy7\"; dkim-atps=neutral","sourceware.org; auth=none"],"Received":["from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xzQ5K54yzz9t32\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat, 23 Sep 2017 06:27:33 +1000 (AEST)","(qmail 65893 invoked by alias); 22 Sep 2017 20:27:20 -0000","(qmail 65830 invoked by uid 89); 22 Sep 2017 20:27:20 -0000"],"DomainKey-Signature":"a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:from:to:subject:date:message-id:in-reply-to\n\t:references; q=dns; s=default; b=fuEvTfrnkcZBye/H9AJKEQ0OhjuEKrK\n\tkETnfCrvF6/19yg37NNJb760kJ00c96MPqsX9re8y2D8vmCmAbwyrI7dYMjE+Z+n\n\tdex1uGumrdgGDJN3LlGsgKbag2lB/AkYrxbPLeqJE0vk9ZIurfD9x9Sf75jm/6ct\n\t+0yzzdtTimHs=","DKIM-Signature":"v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id\n\t:list-unsubscribe:list-subscribe:list-archive:list-post\n\t:list-help:sender:from:to:subject:date:message-id:in-reply-to\n\t:references; s=default; bh=axGVktEMVS7PGmcrcjGyblikYdA=; b=PxRfN\n\tNy7FD7954ILuK2Zaniv+pBHqaHBO7k182YySBwIG69Ig7U44KevcWIJv3hMK05ZW\n\t1A+GwHBRH6ZduW8bUMueqD16AJRxOMYooMt/kpjDmrs97IhfnQeCmBnQg2EIB+vO\n\t55HIMc/STUONWz3Zqul5LRWLyQYQQACyMuER5c=","Mailing-List":"contact libc-alpha-help@sourceware.org; run by ezmlm","Precedence":"bulk","List-Id":"<libc-alpha.sourceware.org>","List-Unsubscribe":"<mailto:libc-alpha-unsubscribe-incoming=patchwork.ozlabs.org@sourceware.org>","List-Subscribe":"<mailto:libc-alpha-subscribe@sourceware.org>","List-Archive":"<http://sourceware.org/ml/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-help@sourceware.org>,\n\t<http://sourceware.org/ml/#faqs>","Sender":"libc-alpha-owner@sourceware.org","X-Virus-Found":"No","X-Spam-SWARE-Status":"No, score=-26.4 required=5.0 tests=BAYES_00, GIT_PATCH_0,\n\tGIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE,\n\tRCVD_IN_SORBS_SPAM,\n\tSPF_PASS autolearn=ham version=3.3.2 spammy=cancellation","X-HELO":"mail-qt0-f175.google.com","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=1GXfV7+fvees1p1zROHg7jrSljERKpLwOTkfFqApNEU=;\n\tb=mTcqduvrIkzzR2XjFCoRYhD9DMUq8/cSiTudYvft7EPmWwoS7CuW/ut+k8PT/caV23\n\tQuHtyHuMOVn8ZIG7ObCY6CHXzoU6kOwog9MYj+UFcupLWcIVWZz0vHqBtDfvyTLJUrFy\n\tvSXp/emglUSas6pFoIgJKUVsLt3ToWxSaZG446z/fn2Q32amNhq3J18nGq5sjwmFB7Uq\n\tfuZgCsxOPylTE8EIF7UqlY2YYZFHwgi7bOHEj7kYFIoRMImat/SRmLlZ/tyBFTvc6wLY\n\tkjORWi5KKYxf5LutYZfFa1ioaZjAxrZnvP7SVk30etOELVra3XRlVhYJA1Ww5nwUQIiG\n\tJ+fA==","X-Gm-Message-State":"AHPjjUjdIPcd6+KXVcwcJBG5MM1HzFge3+r/8GKLkGYuUBHNG/E/rciH\n\tuVsjV/mhBazCnHVUOBeqTM3A16XhVV0=","X-Google-Smtp-Source":"AOwi7QByxciOZABWz0KsoiaZ2K7SNPccoaFb7ybZCZVCH/6eTilx3SPKHkh9k7BOkdBDBuoRmOAzxg==","X-Received":"by 10.237.42.79 with SMTP id k15mr624421qtf.222.1506112033148;\n\tFri, 22 Sep 2017 13:27:13 -0700 (PDT)","From":"Adhemerval Zanella <adhemerval.zanella@linaro.org>","To":"libc-alpha@sourceware.org","Subject":"[PATCH 1/8] nptl: Add C11 threads thrd_* functions","Date":"Fri, 22 Sep 2017 17:26:57 -0300","Message-Id":"<1506112024-22601-2-git-send-email-adhemerval.zanella@linaro.org>","In-Reply-To":"<1506112024-22601-1-git-send-email-adhemerval.zanella@linaro.org>","References":"<1506112024-22601-1-git-send-email-adhemerval.zanella@linaro.org>"},"content":"This patch adds the thrd_* definitions from C11 threads (ISO/IEC 9899:2011),\nmore specifically thrd_create, thrd_curent, rhd_detach, thrd_equal,\nthrd_exit, thrd_join, thrd_sleep, thrd_yield, and required types.\n\nMostly of the definitions are composed based on POSIX conterparts, such as\nthrd_t (using pthread_t).  For thrd_* function internally direct\nPOSIX pthread call are used with the exceptions:\n\n  1. thrd_start uses pthread_create internal implementation, but changes\n     how to actually calls the start routine.  This is due the difference\n     in signature between POSIX and C11, where former return a 'void *'\n     and latter 'int'.\n     To avoid calling convention issues due 'void *' to int cast, routines\n     from C11 threads are started slight different than default pthread one.\n     Explicit cast to expected return are used internally on pthread_create\n     and the result is stored back to void also with an explicit cast.\n\n  2. thrd_sleep uses nanosleep internal direct syscall to avoid clobbering\n     errno, to handle expected standard return codes, and to avoid making\n     the call a POSIX cancellation entrypoint.\n\n  3. thrd_yield also uses internal direct syscall to avoid errno clobbering.\n\nChecked with a build for all major ABI (aarch64-linux-gnu, alpha-linux-gnu,\narm-linux-gnueabi, i386-linux-gnu, ia64-linux-gnu, m68k-linux-gnu,\nmicroblaze-linux-gnu [1], mips{64}-linux-gnu, nios2-linux-gnu,\npowerpc{64le}-linux-gnu, s390{x}-linux-gnu, sparc{64}-linux-gnu,\ntile{pro,gx}-linux-gnu, and x86_64-linux-gnu).\n\nAlso ran a full check on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu,\narm-linux-gnueabhf, and powerpc64le-linux-gnu.\n\n\t* conform/Makefile (conformtest-headers-ISO11): Add threads.h.\n\t(linknamespace-libs-ISO11): Add libpthread.a.\n\t* conform/data/threads.h-data: New file: add C11 thrd_* types and\n\tfunctions.\n\t* include/stdc-predef.h (__STDC_NO_THREADS__): Remove definition.\n\t* nptl/Makefile (headers): Add threads.h.\n\t(libpthread-routines): Add new C11 thread thrd_create, thrd_current,\n\tthrd_detach, thrd_equal, thrd_exit, thrd_join, thrd_sleep, and\n\tthrd_yield.\n\t* nptl/Versions (libpthread) [GLIBC_2.27]): Add new C11 thread\n\tthrd_create, thrd_current, thrd_detach, thrd_equal, thrd_exit,\n\tthrd_join, thrd_sleep, and thrd_yield symbols.\n\t* nptl/descr.h (struct pthread): Add c11 field.\n\t* nptl/pthreadP.h (ATTR_C11_THREAD): New define.\n\t* nptl/pthread_create.c (START_THREAD_DEFN): Call C11 thread start\n\troutine with expected function prototype.\n\t(__pthread_create_2_1): Add C11 threads check based on attribute\n\tvalue.\n\t* nptl/thrd_create.c: New file.\n\t* nptl/thrd_current.c: Likewise.\n\t* nptl/thrd_detach.c: Likewise.\n\t* nptl/thrd_equal.c: Likewise.\n\t* nptl/thrd_exit.c: Likewise.\n\t* nptl/thrd_join.c: Likewise.\n\t* nptl/thrd_priv.h: Likewise.\n\t* nptl/thrd_sleep.c: Likewise.\n\t* nptl/thrd_yield.c: Likewise.\n\t* sysdeps/nptl/threads.h: Likewise.\n---\n ChangeLog                   | 31 ++++++++++++++++\n conform/Makefile            |  7 ++--\n conform/data/threads.h-data | 23 ++++++++++++\n include/stdc-predef.h       |  3 --\n nptl/Makefile               |  6 ++-\n nptl/Versions               |  6 +++\n nptl/descr.h                |  2 +\n nptl/pthreadP.h             |  3 ++\n nptl/pthread_create.c       | 18 ++++++++-\n nptl/thrd_create.c          | 32 ++++++++++++++++\n nptl/thrd_current.c         | 26 +++++++++++++\n nptl/thrd_detach.c          | 30 +++++++++++++++\n nptl/thrd_equal.c           | 26 +++++++++++++\n nptl/thrd_exit.c            | 27 ++++++++++++++\n nptl/thrd_join.c            | 32 ++++++++++++++++\n nptl/thrd_priv.h            | 46 +++++++++++++++++++++++\n nptl/thrd_sleep.c           | 41 +++++++++++++++++++++\n nptl/thrd_yield.c           | 29 +++++++++++++++\n sysdeps/nptl/threads.h      | 90 +++++++++++++++++++++++++++++++++++++++++++++\n 19 files changed, 468 insertions(+), 10 deletions(-)\n create mode 100644 conform/data/threads.h-data\n create mode 100644 nptl/thrd_create.c\n create mode 100644 nptl/thrd_current.c\n create mode 100644 nptl/thrd_detach.c\n create mode 100644 nptl/thrd_equal.c\n create mode 100644 nptl/thrd_exit.c\n create mode 100644 nptl/thrd_join.c\n create mode 100644 nptl/thrd_priv.h\n create mode 100644 nptl/thrd_sleep.c\n create mode 100644 nptl/thrd_yield.c\n create mode 100644 sysdeps/nptl/threads.h","diff":"diff --git a/conform/Makefile b/conform/Makefile\nindex 3883a4b..9e00d41 100644\n--- a/conform/Makefile\n+++ b/conform/Makefile\n@@ -34,9 +34,9 @@ conformtest-headers-ISO := assert.h ctype.h errno.h float.h limits.h locale.h \\\n conformtest-headers-ISO99 := $(conformtest-headers-ISO) complex.h fenv.h \\\n \t\t\t     inttypes.h iso646.h stdbool.h stdint.h tgmath.h \\\n \t\t\t     wchar.h wctype.h\n-# Missing ISO11 expectations for: stdatomic.h threads.h.\n+# Missing ISO11 expectations for: stdatomic.h\n conformtest-headers-ISO11 := $(conformtest-headers-ISO99) stdalign.h \\\n-\t\t\t     stdnoreturn.h uchar.h\n+\t\t\t     stdnoreturn.h threads.h uchar.h\n conformtest-headers-POSIX := $(conformtest-headers-ISO) aio.h dirent.h \\\n \t\t\t     fcntl.h fnmatch.h glob.h grp.h mqueue.h \\\n \t\t\t     pthread.h pwd.h regex.h sched.h semaphore.h \\\n@@ -197,7 +197,8 @@ linknamespace-libs-xsi = $(linknamespace-libs-posix) \\\n \t\t\t $(common-objpfx)crypt/libcrypt.a\n linknamespace-libs-ISO = $(linknamespace-libs-isoc)\n linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)\n-linknamespace-libs-ISO11 = $(linknamespace-libs-isoc)\n+linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \\\n+\t\t\t   $(common-objpfx)nptl/libpthread.a\n linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \\\n \t\t\t  $(common-objpfx)crypt/libcrypt.a\n linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)\ndiff --git a/conform/data/threads.h-data b/conform/data/threads.h-data\nnew file mode 100644\nindex 0000000..bc2d857\n--- /dev/null\n+++ b/conform/data/threads.h-data\n@@ -0,0 +1,23 @@\n+#if defined ISO11\n+\n+constant thrd_success\n+constant thrd_busy\n+constant thrd_error\n+constant thrd_nomem\n+constant thrd_timedout\n+\n+type thrd_t\n+type thrd_start_t\n+\n+function int thrd_create (thrd_t*, thrd_start_t, void*)\n+function int thrd_equal (thrd_t, thrd_t)\n+function thrd_t thrd_current (void)\n+function int thrd_sleep (const struct timespec*, struct timespec*)\n+function void thrd_exit (int)\n+function int thrd_detach (thrd_t)\n+function int thrd_join (thrd_t, int*)\n+function void thrd_yield (void)\n+\n+#include \"time.h-data\"\n+\n+#endif\ndiff --git a/include/stdc-predef.h b/include/stdc-predef.h\nindex 74ade90..1cd3d73 100644\n--- a/include/stdc-predef.h\n+++ b/include/stdc-predef.h\n@@ -57,7 +57,4 @@\n    - 3 additional Zanabazar Square characters */\n #define __STDC_ISO_10646__\t\t201706L\n \n-/* We do not support C11 <threads.h>.  */\n-#define __STDC_NO_THREADS__\t\t1\n-\n #endif\ndiff --git a/nptl/Makefile b/nptl/Makefile\nindex d819349..31761a6 100644\n--- a/nptl/Makefile\n+++ b/nptl/Makefile\n@@ -22,7 +22,7 @@ subdir\t:= nptl\n \n include ../Makeconfig\n \n-headers := pthread.h semaphore.h bits/semaphore.h\n+headers := pthread.h semaphore.h bits/semaphore.h threads.h\n \n extra-libs := libpthread\n extra-libs-others := $(extra-libs)\n@@ -138,7 +138,9 @@ libpthread-routines = nptl-init vars events version pt-interp \\\n \t\t      pthread_mutex_getprioceiling \\\n \t\t      pthread_mutex_setprioceiling \\\n \t\t      pthread_setname pthread_getname \\\n-\t\t      pthread_setattr_default_np pthread_getattr_default_np\n+\t\t      pthread_setattr_default_np pthread_getattr_default_np \\\n+\t\t      thrd_create thrd_current thrd_detach thrd_equal \\\n+\t\t      thrd_exit thrd_join thrd_sleep thrd_yield\n #\t\t      pthread_setuid pthread_seteuid pthread_setreuid \\\n #\t\t      pthread_setresuid \\\n #\t\t      pthread_setgid pthread_setegid pthread_setregid \\\ndiff --git a/nptl/Versions b/nptl/Versions\nindex 0ae5def..a282ceb 100644\n--- a/nptl/Versions\n+++ b/nptl/Versions\n@@ -265,6 +265,12 @@ libpthread {\n   GLIBC_2.22 {\n   }\n \n+  # C11 thread symbols.\n+  GLIBC_2.27 {\n+    thrd_create; thrd_current; thrd_detach; thrd_equal; thrd_exit; thrd_join;\n+    thrd_sleep; thrd_yield;\n+  }\n+\n   GLIBC_PRIVATE {\n     __pthread_initialize_minimal;\n     __pthread_clock_gettime; __pthread_clock_settime;\ndiff --git a/nptl/descr.h b/nptl/descr.h\nindex c5ad0c8..c1ff711 100644\n--- a/nptl/descr.h\n+++ b/nptl/descr.h\n@@ -371,6 +371,8 @@ struct pthread\n      to the function.  */\n   void *(*start_routine) (void *);\n   void *arg;\n+  /* Indicates whether is a C11 thread created by thrd_creat.  */\n+  bool c11;\n \n   /* Debug state.  */\n   td_eventbuf_t eventbuf;\ndiff --git a/nptl/pthreadP.h b/nptl/pthreadP.h\nindex dbf46b0..ded7547 100644\n--- a/nptl/pthreadP.h\n+++ b/nptl/pthreadP.h\n@@ -173,6 +173,9 @@ enum\n #define __PTHREAD_ONCE_DONE\t\t2\n #define __PTHREAD_ONCE_FORK_GEN_INCR\t4\n \n+/* Attribute to indicate thread creation was issued from C11 thrd_create.  */\n+#define ATTR_C11_THREAD ((void*)(uintptr_t)-1)\n+\n \n /* Condition variable definitions.  See __pthread_cond_wait_common.\n    Need to be defined here so there is one place from which\ndiff --git a/nptl/pthread_create.c b/nptl/pthread_create.c\nindex 992331e..bef3042 100644\n--- a/nptl/pthread_create.c\n+++ b/nptl/pthread_create.c\n@@ -460,7 +460,19 @@ START_THREAD_DEFN\n       LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);\n \n       /* Run the code the user provided.  */\n-      THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));\n+      void *ret;\n+      if (pd->c11)\n+\t{\n+\t  /* The function pointer of the c11 thread start is cast to an incorrect\n+\t     type on __pthread_create_2_1 call, however it is casted back to correct\n+\t     one so the call behavior is well-defined (it is assumed that pointers\n+\t     to void are able to represent all values of int.  */\n+\t  int (*start)(void*) = (int (*) (void*)) pd->start_routine;\n+\t  ret = (void*) (intptr_t) start (pd->arg);\n+\t}\n+      else\n+\tret = pd->start_routine (pd->arg);\n+      THREAD_SETMEM (pd, result, ret);\n     }\n \n   /* Call destructors for the thread_local TLS variables.  */\n@@ -613,7 +625,8 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,\n   const struct pthread_attr *iattr = (struct pthread_attr *) attr;\n   struct pthread_attr default_attr;\n   bool free_cpuset = false;\n-  if (iattr == NULL)\n+  bool c11 = (attr == ATTR_C11_THREAD);\n+  if (iattr == NULL || c11)\n     {\n       lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);\n       default_attr = __default_pthread_attr;\n@@ -671,6 +684,7 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,\n      get the information from its thread descriptor.  */\n   pd->start_routine = start_routine;\n   pd->arg = arg;\n+  pd->c11 = c11;\n \n   /* Copy the thread attribute flags.  */\n   struct pthread *self = THREAD_SELF;\ndiff --git a/nptl/thrd_create.c b/nptl/thrd_create.c\nnew file mode 100644\nindex 0000000..0b6b822\n--- /dev/null\n+++ b/nptl/thrd_create.c\n@@ -0,0 +1,32 @@\n+/* C11 threads thread creation implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Create a new thread executing the function func.  Arguments to func\n+   are passed through arg.  If succesful, thr is set to new thread\n+   identifier.  */\n+int\n+thrd_create (thrd_t *thr, thrd_start_t func, void *arg)\n+{\n+  _Static_assert (sizeof (thr) == sizeof (pthread_t), \"thrd_t size\");\n+\n+  int err_code = __pthread_create_2_1 (thr, ATTR_C11_THREAD,\n+\t\t\t\t       (void* (*) (void*))func, arg);\n+  return thrd_err_map (err_code);\n+}\ndiff --git a/nptl/thrd_current.c b/nptl/thrd_current.c\nnew file mode 100644\nindex 0000000..7269d4b\n--- /dev/null\n+++ b/nptl/thrd_current.c\n@@ -0,0 +1,26 @@\n+/* C11 threads current thread implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Return current thread identifier.  */\n+thrd_t\n+thrd_current (void)\n+{\n+  return __pthread_self ();\n+}\ndiff --git a/nptl/thrd_detach.c b/nptl/thrd_detach.c\nnew file mode 100644\nindex 0000000..187d078\n--- /dev/null\n+++ b/nptl/thrd_detach.c\n@@ -0,0 +1,30 @@\n+/* C11 threads thread detach implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Detache the thread identified by thr from the current environment.\n+   It does not allow join or wait for the thread.  */\n+int\n+thrd_detach (thrd_t thr)\n+{\n+  int err_code;\n+\n+  err_code = __pthread_detach (thr);\n+  return thrd_err_map (err_code);\n+}\ndiff --git a/nptl/thrd_equal.c b/nptl/thrd_equal.c\nnew file mode 100644\nindex 0000000..fcda488\n--- /dev/null\n+++ b/nptl/thrd_equal.c\n@@ -0,0 +1,26 @@\n+/* C11 threads thread equality check implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Check if lhs and rhs point to the same thread.  */\n+int\n+thrd_equal (thrd_t lhs, thrd_t rhs)\n+{\n+  return __pthread_equal (lhs, rhs);\n+}\ndiff --git a/nptl/thrd_exit.c b/nptl/thrd_exit.c\nnew file mode 100644\nindex 0000000..a49d8e0\n--- /dev/null\n+++ b/nptl/thrd_exit.c\n@@ -0,0 +1,27 @@\n+/* C11 threads thread exit implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Terminate current thread execution, cleaning up any thread local\n+   storage and freeing resources.  Returns the value specified in res.  */\n+_Noreturn void\n+thrd_exit (int res)\n+{\n+  __pthread_exit ((void*)(uintptr_t) res);\n+}\ndiff --git a/nptl/thrd_join.c b/nptl/thrd_join.c\nnew file mode 100644\nindex 0000000..1d69918\n--- /dev/null\n+++ b/nptl/thrd_join.c\n@@ -0,0 +1,32 @@\n+/* C11 threads thread join implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Block current thread until execution of thr is complete.  In case that\n+   res is not NULL, will store the return value of thr when exiting.  */\n+int\n+thrd_join (thrd_t thr, int *res)\n+{\n+  void *pthread_res;\n+  int err_code = __pthread_join (thr, &pthread_res);\n+  if (res)\n+   *res = (int)((uintptr_t) pthread_res);\n+\n+  return thrd_err_map (err_code);\n+}\ndiff --git a/nptl/thrd_priv.h b/nptl/thrd_priv.h\nnew file mode 100644\nindex 0000000..a431d60\n--- /dev/null\n+++ b/nptl/thrd_priv.h\n@@ -0,0 +1,46 @@\n+/* Internal C11 threads definitions.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#ifndef THRD_PRIV_H\n+# define THRD_PRIV_H\n+\n+#include <features.h>\n+#include <threads.h>\n+#include <errno.h>\n+#include \"pthreadP.h\"\t/* For pthread_{mutex,cond}_t definitions.  */\n+\n+/* Maps pthread error codes with thrd error codes.  */\n+static __always_inline int\n+thrd_err_map (int err_code)\n+{\n+  switch (err_code)\n+  {\n+    case 0:\n+      return thrd_success;\n+    case ENOMEM:\n+      return thrd_nomem;\n+    case ETIMEDOUT:\n+      return thrd_timedout;\n+    case EBUSY:\n+      return thrd_busy;\n+    default:\n+      return thrd_error;\n+  }\n+}\n+\n+#endif\ndiff --git a/nptl/thrd_sleep.c b/nptl/thrd_sleep.c\nnew file mode 100644\nindex 0000000..a49fdc4\n--- /dev/null\n+++ b/nptl/thrd_sleep.c\n@@ -0,0 +1,41 @@\n+/* C11 threads thread sleep implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+#include <time.h>\n+\n+/* Block current thread execution for at least the time pointed by time_point.\n+   The current thread may resume if receives a signal.  In that case, if\n+   remaining is not NULL, the remaining time is stored in the object pointed\n+   by it.  */\n+int\n+thrd_sleep (const struct timespec* time_point, struct timespec* remaining)\n+{\n+  INTERNAL_SYSCALL_DECL (err);\n+  int ret = INTERNAL_SYSCALL_CALL (nanosleep, err, time_point, remaining);\n+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))\n+    {\n+      /* C11 states thrd_sleep function returns -1 if it has been interrupted\n+         by a signal, or a negative value if it fails.  */\n+      ret = INTERNAL_SYSCALL_ERRNO (ret, err);\n+      if (ret == EINTR)\n+\treturn -1;\n+      return -2;\n+    }\n+  return 0;\n+}\ndiff --git a/nptl/thrd_yield.c b/nptl/thrd_yield.c\nnew file mode 100644\nindex 0000000..13a02f3\n--- /dev/null\n+++ b/nptl/thrd_yield.c\n@@ -0,0 +1,29 @@\n+/* C11 threads thread yield implementation.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#include \"thrd_priv.h\"\n+\n+/* Stop current thread execution and call the scheduler to decide which\n+   thread should execute next.  The current thread may be selected by the\n+   scheduler to keep running.  */\n+void\n+thrd_yield (void)\n+{\n+  INTERNAL_SYSCALL_DECL (err);\n+  INTERNAL_SYSCALL_CALL (sched_yield, err);\n+}\ndiff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h\nnew file mode 100644\nindex 0000000..4b89a30\n--- /dev/null\n+++ b/sysdeps/nptl/threads.h\n@@ -0,0 +1,90 @@\n+/* ISO C11 Standard: 7.26 - Thread support library  <threads.h>.\n+   Copyright (C) 2017 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <http://www.gnu.org/licenses/>.  */\n+\n+#ifndef _THREADS_H\n+#define _THREADS_H\t1\n+\n+#include <features.h>\n+#include <time.h>\n+\n+__BEGIN_DECLS\n+\n+#include <bits/types/struct_timespec.h>\n+\n+typedef unsigned long int thrd_t;\n+typedef int (*thrd_start_t) (void*);\n+\n+/* Exit and error codes.  */\n+enum\n+{\n+  thrd_success  = 0,\n+  thrd_busy     = 1,\n+  thrd_error    = 2,\n+  thrd_nomem    = 3,\n+  thrd_timedout = 4\n+};\n+\n+/* Threads functions.  */\n+\n+/* Create a new thread executing the function __func.  Arguments to __func\n+   are passed through __arg.  If succesful, __thr is set to new thread\n+   identifier.  */\n+extern int thrd_create (thrd_t *__thr, thrd_start_t __func, void *__arg);\n+\n+/* Check if __lhs and __rhs point to the same thread.  */\n+extern int thrd_equal (thrd_t __lhs, thrd_t __rhs);\n+\n+/* Return current thread identifier.  */\n+extern thrd_t thrd_current (void);\n+\n+/* Block current thread execution for at least the time pointed by\n+   __time_point.  The current thread may resume if receives a signal.  In\n+   that case, if __remaining is not NULL, the remaining time is stored in\n+   the object pointed by it.  */\n+extern int thrd_sleep (const struct timespec *__time_point,\n+\t\t       struct timespec *__remaining);\n+\n+/* Terminate current thread execution, cleaning up any thread local\n+   storage and freeing resources.  Returns the value specified in __res.  */\n+extern void thrd_exit (int __res) __attribute__ ((__noreturn__));\n+\n+/* Detache the thread identified by __thr from the current environment.\n+   It does not allow join or wait for __thr.  */\n+extern int thrd_detach (thrd_t __thr);\n+\n+/* Block current thread until execution of __thr is complete.  In case that\n+   __res is not NULL, will store the return value of __thr when exiting.  */\n+extern int thrd_join (thrd_t __thr, int *__res);\n+\n+/* Stop current thread execution and call the scheduler to decide which\n+   thread should execute next.  The current thread may be selected by the\n+   scheduler to keep running.  */\n+extern void thrd_yield (void);\n+\n+#ifdef __USE_EXTERN_INLINES\n+/* Optimizations.  */\n+__extern_inline int\n+thrd_equal (thrd_t __thread1, thrd_t __thread2)\n+{\n+  return __thread1 == __thread2;\n+}\n+#endif\n+\n+__END_DECLS\n+\n+#endif /* _THREADS_H */\n","prefixes":["1/8"]}