From patchwork Fri Sep 22 20:26:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 114090 Delivered-To: patch@linaro.org Received: by 10.80.163.150 with SMTP id s22csp3473659edb; Fri, 22 Sep 2017 13:27:39 -0700 (PDT) X-Received: by 10.99.117.81 with SMTP id f17mr306707pgn.314.1506112059266; Fri, 22 Sep 2017 13:27:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506112059; cv=none; d=google.com; s=arc-20160816; b=GPec4RT8XXnwj9Z5NKNrA2+UCn4vlFjZDZNV3zEw50nudpxQM3TU92LMVFli4QtR7e WMBvm1exRN6GaWYJpBuSEpnImAa+kICZOCq+FLirq2qFnT4Clfij1zCJdKv8TXS2mbWQ tX7ZH95uuaJX5u05ymldXlvgsIT7wpeBUpv2uU7bDvCLTv9WmuFqW87FlT4myQeONKh5 zLJsbC1Z083IedHwbiAKDPk7yRpwio7niGsRKUSL8qulrRMy/WxD8jhPIsW89OAzfSAo 9/lqxyVnRX6trAh9rNA9xmMBzyBncmYgEi7YdLq1WIZKI318dQ52pMAHj4cln9siwF9E VaLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=1GXfV7+fvees1p1zROHg7jrSljERKpLwOTkfFqApNEU=; b=nekbFFN4JArrdNHLsvbyd7p3UwHm8oNoD8+A76kMhCVZ4lCLPD9285WSdLdeiPXuy+ fEpFhYO5eBuDGIJgxtdraIVGAzsZWet/gz+wJfGX3QoSuDXlwfaW8+ZKk8pQgfG4A505 RO9uI1mc949xngH37+N5RdBYnuc+B3g8CI9m4P/WHiuNJi6LuCrm82SeA96RXgh9QnJQ 1bRajDJw3Rg2AoH9maJcxnV+B1KdvmrIw5hdO+0p0G1zm4D3r+pTBQdSX1RLeDqIWTTC YygYEipJdBt93CA8bdkJhcukGEDfcJanihk08G2wpsDMdIkj5yitjoKh9VOoopa22CTp whbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=sovy54uJ; spf=pass (google.com: domain of libc-alpha-return-84874-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-84874-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 6si330114pld.790.2017.09.22.13.27.38 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Sep 2017 13:27:39 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-84874-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=sovy54uJ; spf=pass (google.com: domain of libc-alpha-return-84874-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-84874-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=HFkjDvsSfWPNopHTh+z+y6a2MDAla6R RJ6k63RNWWx266On5ceQ8k4oWR83gtaRlyNdms2+shpqAEChOwoojkJ9AF/lFAzl X4aJ+LaytrPwe/wYuvfOEaj04B/iPhpgt2oovm1yjkjy+ETIvFc3LaysM1Bfbu23 PykSrwq7+ZKY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=axGVktEMVS7PGmcrcjGyblikYdA=; b=sovy5 4uJGOS1ap+jhXTgeHAIQpO5faHr8/tzb7wdGjiMhQgN1bgn2bAYQR7RRqggBW+md ehhlSOgbW9THpd2vOPv5+f+IB1Xl3oz9lHjeD71AjNqDvzj7RCDjEdI7DO9CUTti ZSoqoan2AqANv++2giHpWg3/deXpBghPHIPuYI= Received: (qmail 65893 invoked by alias); 22 Sep 2017 20:27:20 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 65830 invoked by uid 89); 22 Sep 2017 20:27:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_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; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=1GXfV7+fvees1p1zROHg7jrSljERKpLwOTkfFqApNEU=; b=mTcqduvrIkzzR2XjFCoRYhD9DMUq8/cSiTudYvft7EPmWwoS7CuW/ut+k8PT/caV23 QuHtyHuMOVn8ZIG7ObCY6CHXzoU6kOwog9MYj+UFcupLWcIVWZz0vHqBtDfvyTLJUrFy vSXp/emglUSas6pFoIgJKUVsLt3ToWxSaZG446z/fn2Q32amNhq3J18nGq5sjwmFB7Uq fuZgCsxOPylTE8EIF7UqlY2YYZFHwgi7bOHEj7kYFIoRMImat/SRmLlZ/tyBFTvc6wLY kjORWi5KKYxf5LutYZfFa1ioaZjAxrZnvP7SVk30etOELVra3XRlVhYJA1Ww5nwUQIiG J+fA== X-Gm-Message-State: AHPjjUjdIPcd6+KXVcwcJBG5MM1HzFge3+r/8GKLkGYuUBHNG/E/rciH uVsjV/mhBazCnHVUOBeqTM3A16XhVV0= X-Google-Smtp-Source: AOwi7QByxciOZABWz0KsoiaZ2K7SNPccoaFb7ybZCZVCH/6eTilx3SPKHkh9k7BOkdBDBuoRmOAzxg== X-Received: by 10.237.42.79 with SMTP id k15mr624421qtf.222.1506112033148; Fri, 22 Sep 2017 13:27:13 -0700 (PDT) From: Adhemerval Zanella 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> 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 | 32 ++++++++++++++++ nptl/thrd_current.c | 26 +++++++++++++ nptl/thrd_detach.c | 30 +++++++++++++++ nptl/thrd_equal.c | 26 +++++++++++++ nptl/thrd_exit.c | 27 ++++++++++++++ nptl/thrd_join.c | 32 ++++++++++++++++ nptl/thrd_priv.h | 46 +++++++++++++++++++++++ nptl/thrd_sleep.c | 41 +++++++++++++++++++++ nptl/thrd_yield.c | 29 +++++++++++++++ sysdeps/nptl/threads.h | 90 +++++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 468 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 diff --git a/conform/Makefile b/conform/Makefile index 3883a4b..9e00d41 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 74ade90..1cd3d73 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 . */ -#define __STDC_NO_THREADS__ 1 - #endif diff --git a/nptl/Makefile b/nptl/Makefile index d819349..31761a6 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) @@ -138,7 +138,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..a282ceb 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -265,6 +265,12 @@ libpthread { GLIBC_2.22 { } + # C11 thread symbols. + GLIBC_2.27 { + 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 c5ad0c8..c1ff711 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 dbf46b0..ded7547 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 992331e..bef3042 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..0b6b822 --- /dev/null +++ b/nptl/thrd_create.c @@ -0,0 +1,32 @@ +/* C11 threads thread creation implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* Create a new thread executing the function func. Arguments to func + are passed through arg. If succesful, thr is set to new thread + identifier. */ +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..7269d4b --- /dev/null +++ b/nptl/thrd_current.c @@ -0,0 +1,26 @@ +/* C11 threads current thread implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* Return current thread identifier. */ +thrd_t +thrd_current (void) +{ + return __pthread_self (); +} diff --git a/nptl/thrd_detach.c b/nptl/thrd_detach.c new file mode 100644 index 0000000..187d078 --- /dev/null +++ b/nptl/thrd_detach.c @@ -0,0 +1,30 @@ +/* C11 threads thread detach implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* Detache the thread identified by thr from the current environment. + It does not allow join or wait for the thread. */ +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..fcda488 --- /dev/null +++ b/nptl/thrd_equal.c @@ -0,0 +1,26 @@ +/* C11 threads thread equality check implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* Check if lhs and rhs point to the same thread. */ +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..a49d8e0 --- /dev/null +++ b/nptl/thrd_exit.c @@ -0,0 +1,27 @@ +/* C11 threads thread exit implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* Terminate current thread execution, cleaning up any thread local + storage and freeing resources. Returns the value specified in res. */ +_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..1d69918 --- /dev/null +++ b/nptl/thrd_join.c @@ -0,0 +1,32 @@ +/* C11 threads thread join implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* 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. */ +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..a431d60 --- /dev/null +++ b/nptl/thrd_priv.h @@ -0,0 +1,46 @@ +/* Internal C11 threads definitions. + Copyright (C) 2017 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 + . */ + +#ifndef THRD_PRIV_H +# define THRD_PRIV_H + +#include +#include +#include +#include "pthreadP.h" /* For pthread_{mutex,cond}_t definitions. */ + +/* Maps pthread error codes with thrd error codes. */ +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..a49fdc4 --- /dev/null +++ b/nptl/thrd_sleep.c @@ -0,0 +1,41 @@ +/* C11 threads thread sleep implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" +#include + +/* 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. */ +int +thrd_sleep (const struct timespec* time_point, struct timespec* remaining) +{ + 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..13a02f3 --- /dev/null +++ b/nptl/thrd_yield.c @@ -0,0 +1,29 @@ +/* C11 threads thread yield implementation. + Copyright (C) 2017 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 + . */ + +#include "thrd_priv.h" + +/* 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. */ +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..4b89a30 --- /dev/null +++ b/sysdeps/nptl/threads.h @@ -0,0 +1,90 @@ +/* ISO C11 Standard: 7.26 - Thread support library . + Copyright (C) 2017 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 + . */ + +#ifndef _THREADS_H +#define _THREADS_H 1 + +#include +#include + +__BEGIN_DECLS + +#include + +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 to __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__)); + +/* Detache the thread identified by __thr from the current environment. + It does not allow join or wait for __thr. */ +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 */