From patchwork Fri Feb 2 17:04:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 126754 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp818885ljc; Fri, 2 Feb 2018 09:05:25 -0800 (PST) X-Google-Smtp-Source: AH8x227dsa6N9PX8je1q8/v1/UZFmXgY2cFqJfSJOpYq1ApnCo8uinS7UdH5hXC83mmgZbFHKE74 X-Received: by 10.99.121.132 with SMTP id u126mr32392070pgc.275.1517591125801; Fri, 02 Feb 2018 09:05:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517591125; cv=none; d=google.com; s=arc-20160816; b=LeqQAZHqOR8D9W2rHs3MZuSeIB0Mjjmi7GkY+bSKHH1AiJcOenxH0nrOs4k+9M/c5c s42G1tlNVa6PGmDExSPy5LQXphwVlvXyNaCCSey5HyYvGdlCFi+8zYCMdPoLwH2VMV13 aUerViTxDxoifS1XyXwgBgVXoVVym6cnaRlmA8FwYs+Z0tkQSQg64/k8d8XrGDIiyfGQ 27tG8H+DNsIKzq6uxb5/j/EZlkDgA4h/iOb0mk8UPN/Yhrnbb/ABhlQUBZH++8gZPzd5 uGpt1sufzZcE6frnbSFrQ80KpB0vebElxraMpLn7N7eCjB96J0sAGvfScWwGWB9ZfpBY K3lw== 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=3uG2sCeKzT7Upl1+pM9OR+DAwZqmksNyv4nt5SLBWPE=; b=VxQ5gJO9hLvMLfJZTgUuiVUmrpMj13yevKYDIOO7vC7wugAIlDSTlPz2JFfryQrLFM y7M5g5x3eC5JUMq4cfqUX2sc42IImyRa3qpKBd1sAoHe3UrgnXikGlkyZWG2SXgYyZrl 3ZLwtbIW+T4IpGrOWw09ASoXvCkuLeR8OizmLd8QaW/jh7dwQIFsz0IKcflIyKDduGB2 Nr8k+lqgmt5Y/u3WZdBok+nIs++Dl9MfkLe0R1MGWPXKRFUIIJwcKOo5LW3W4VkzcG/e llKe9sLgsbKpJQt1BL31JoagrVT25wIZSgXZ81dlEVhCVQeDZ3xNCzbXCn0Bo55LHZ1r VVrQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=OIXMJ7Mt; spf=pass (google.com: domain of libc-alpha-return-89922-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-89922-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 l33-v6si2124038pld.692.2018.02.02.09.05.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Feb 2018 09:05:25 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-89922-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=OIXMJ7Mt; spf=pass (google.com: domain of libc-alpha-return-89922-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-89922-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=ONf2A5W0Mhn0F5l64+7Y4ZKpV69lFKn oRVxEzVHky1LCsIWWDnklEQ3CD7deeoVMqvAfAlRv2q0ZDzT4FN9CKLEprpox7ID rq6dS+1YMgUFXYEHMyk1zjlMoYOe2UtzeN0levrl370GrgX3lZzGCNDwlH1jZBqQ O8h34hNxiRao= 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=MYdqdXK8WX0cKH/FZyrGYR6qoww=; b=OIXMJ 7Mtt1wZoxbMdp4WBud48iUhukE+uY6HHZHcsuIxS+R5sMz+hDta4ARfeEpQo1EcZ zKmpQHqEMRD8MEYnujoZCkxpL7Jh9AzmiVW3PzW+FQOj0+3N4cGsN0CxyxrKdaYV WJiyP6/P+dO9W4QOCDcmmb5vvtaekAFIbSBK4w= Received: (qmail 129055 invoked by alias); 2 Feb 2018 17:05:02 -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 128878 invoked by uid 89); 2 Feb 2018 17:05:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=freeing, thr X-HELO: mail-qt0-f182.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=3uG2sCeKzT7Upl1+pM9OR+DAwZqmksNyv4nt5SLBWPE=; b=egFnjJ02kVHMTb4od7dciv0hoOZrjDewRtA97PdHaiHWl/qiRzjNkI9iKf2Ny0uEQS zT9pMVapSGzHW+DK0ttQogrbtXdv3gCzJQsFy1g77jCJeT/u9WwePRIR8W72VkCYLlp4 u1oZC0S5zKuHt2pAsitCxwHfsfnxj+VNrnqXN20GLR8uIhxeBxhKl6pjLjyi+h+jbILS 9cseRMugxytisl7nJGkg6QMGtid8V6mX2w8Vg98bmIcB9D6wfu+f9EHnxkGwZqq9Txxl 39FwDWdzCuhCpDotY/BgpVHBU+Bz8f9Nl/67uIRdt5yp+l3MTuV2Y0+njQeoGVdcssho fgxw== X-Gm-Message-State: AKwxytcENP1X8mchh7BHyjpoiKhAwVXOvMRQDoNswMkbX3xd+o8KurkH 8/T34c7Jbi+WxtgMcoqilLTDvW2Ba90= X-Received: by 10.237.56.137 with SMTP id k9mr49908539qte.35.1517591093723; Fri, 02 Feb 2018 09:04:53 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v8 1/8] nptl: Add C11 threads thrd_* functions Date: Fri, 2 Feb 2018 15:04:37 -0200 Message-Id: <1517591084-11347-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517591084-11347-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517591084-11347-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 | 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 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 . */ -#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 + . */ + +#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 + . */ + +#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 + . */ + +#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 + . */ + +#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 + . */ + +#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 + . */ + +#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 + . */ + +#ifndef THRD_PRIV_H +# define THRD_PRIV_H + +#include +#include +#include +#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 + . */ + +#include "thrd_priv.h" +#include + +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 + . */ + +#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 . + 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 + . */ + +#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 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 */