From patchwork Wed Jul 25 18:28:53 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: 28613 Received: (qmail 124477 invoked by alias); 25 Jul 2018 18:29:05 -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 124462 invoked by uid 89); 25 Jul 2018 18:29:04 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=edition, 10.0, Square X-HELO: mail-qk0-f196.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=subject:to:cc:references:from:openpgp:autocrypt:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=chriGdiQkbHpSm4J0ZJ89w1/RolhqkB98LmpmLmMtlY=; b=MyUhJpOgNcK8lEvQjkLj14kyYD13EHJIgUoJ3SApDyrDQdhQZcQaswGmMuXJjDGigs zZvSiv4zqf5h3X8t3qNtAT0t/oFZ4KzCVlDYqzf8dqMP/GG+mX2bvyKM0RDDUx1fSggp L0bH+Pxbp9z7cizM+5p28Xe2se6SGefuxC1wg= Return-Path: Subject: Re: [PATCH] Fix C11 conformance issues To: Joseph Myers Cc: libc-alpha@sourceware.org References: <1532526205-5708-1-git-send-email-adhemerval.zanella@linaro.org> From: Adhemerval Zanella Openpgp: preference=signencrypt Message-ID: <0956cfd7-0f67-42fa-dee3-5aa12e5b554c@linaro.org> Date: Wed, 25 Jul 2018 15:28:53 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: On 25/07/2018 12:40, Joseph Myers wrote: > On Wed, 25 Jul 2018, Adhemerval Zanella wrote: > >> Checked on i686-linux-gnu and i686-gnu. >> >> * include/threads.h: Move to ... >> * sysdeps/nptl/threads.h: ... here. >> * sysdeps/htl/threads.h: New file. > > To confirm: nptl/threads.h, not the wrapper you're moving, still gets > correctly installed as threads.h after this patch, while it remains the > case that no threads.h is installed for Hurd? > > I think you need two separate versions of stdc-predef.h as well, so that > Hurd gets a version that defines __STDC_NO_THREADS__. Then once there is > a C11 threads implementation for HTL, we can move back to just having a > single version of stdc-predef.h. (There should also be a single version > of threads.h in that case, and we should aim to move towards a single > pthread.h shared between NPTL and HTL as well.) > The patch below should fix it and the hurd specific stdc-predef.h with __STDC_NO_THREADS__ defined. I would like to avoid duplicating a file contents, but the other possible alternative which I can think of would add a platform specific file (empty for nptl case and defining __STDC_NO_THREADS__ for htl) with the drawback of adding another include on every compilation (due extra include). I think we can live with a hurd specific stdc-predef.h for now. Reviewed-by: Carlos O'Donell --- [PATCH] Fix ISO C threads installed header and HURD assumption Checked on both i686-linux-gnu and i686-gnu that both threads.h and stdc-predef.h are the expected ones. * nptl/threads.h: Move to ... * sysdeps/nptl/threads.h: ... here. * sysdeps/hurd/stdc-predef.h: New file. --- ChangeLog | 6 ++ nptl/threads.h | 207 -------------------------------------------- sysdeps/hurd/stdc-predef.h | 63 ++++++++++++++ sysdeps/nptl/threads.h | 208 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 276 insertions(+), 208 deletions(-) delete mode 100644 nptl/threads.h create mode 100644 sysdeps/hurd/stdc-predef.h diff --git a/nptl/threads.h b/nptl/threads.h deleted file mode 100644 index 9800f93..0000000 --- a/nptl/threads.h +++ /dev/null @@ -1,207 +0,0 @@ -/* 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 -#include - -#ifndef __cplusplus -# define thread_local _Thread_local -#endif - -#define TSS_DTOR_ITERATIONS 4 -typedef unsigned int tss_t; -typedef void (*tss_dtor_t) (void*); - -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 -}; - -/* Mutex types. */ -enum -{ - mtx_plain = 0, - mtx_recursive = 1, - mtx_timed = 2 -}; - -typedef struct -{ - int __data __ONCE_ALIGNMENT; -} once_flag; -#define ONCE_FLAG_INIT { 0 } - -typedef union -{ - char __size[__SIZEOF_PTHREAD_MUTEX_T]; - long int __align __LOCK_ALIGNMENT; -} mtx_t; - -typedef union -{ - char __size[__SIZEOF_PTHREAD_COND_T]; - __extension__ long long int __align __LOCK_ALIGNMENT; -} cnd_t; - -/* 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 - (it 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 - - -/* Mutex functions. */ - -/* Creates a new mutex object with type __TYPE. If successful the new - object is pointed by __MUTEX. */ -extern int mtx_init (mtx_t *__mutex, int __type); - -/* Block the current thread until the mutex pointed to by __MUTEX is - unlocked. In that case current thread will not be blocked. */ -extern int mtx_lock (mtx_t *__mutex); - -/* Block the current thread until the mutex pointed by __MUTEX is unlocked - or time pointed by __TIME_POINT is reached. In case the mutex is unlock, - the current thread will not be blocked. */ -extern int mtx_timedlock (mtx_t *__restrict __mutex, - const struct timespec *__restrict __time_point); - -/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex - is free the current threads takes control of it, otherwise it returns - immediately. */ -extern int mtx_trylock (mtx_t *__mutex); - -/* Unlock the mutex pointed by __MUTEX. It may potentially awake other - threads waiting on this mutex. */ -extern int mtx_unlock (mtx_t *__mutex); - -/* Destroy the mutex object pointed by __MUTEX. */ -extern void mtx_destroy (mtx_t *__mutex); - - -/* Call function __FUNC exactly once, even if invoked from several threads. - All calls must be made with the same __FLAGS object. */ -extern void call_once (once_flag *__flag, void (*__func)(void)); - - -/* Condition variable functions. */ - -/* Initialize new condition variable pointed by __COND. */ -extern int cnd_init (cnd_t *__cond); - -/* Unblock one thread that currently waits on condition variable pointed - by __COND. */ -extern int cnd_signal (cnd_t *__cond); - -/* Unblock all threads currently waiting on condition variable pointed by - __COND. */ -extern int cnd_broadcast (cnd_t *__cond); - -/* Block current thread on the condition variable pointed by __COND. */ -extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); - -/* Block current thread on the condition variable until condition variable - pointed by __COND is signaled or time pointed by __TIME_POINT is - reached. */ -extern int cnd_timedwait (cnd_t *__restrict __cond, - mtx_t *__restrict __mutex, - const struct timespec *__restrict __time_point); - -/* Destroy condition variable pointed by __cond and free all of its - resources. */ -extern void cnd_destroy (cnd_t *__COND); - - -/* Thread specific storage functions. */ - -/* Create new thread-specific storage key and stores it in the object pointed - by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when - the thread terminates. */ -extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); - -/* Return the value held in thread-specific storage for the current thread - identified by __TSS_ID. */ -extern void *tss_get (tss_t __tss_id); - -/* Sets the value of the thread-specific storage identified by __TSS_ID for - the current thread to __VAL. */ -extern int tss_set (tss_t __tss_id, void *__val); - -/* Destroys the thread-specific storage identified by __TSS_ID. The - destructor is not called until thrd_exit is called. */ -extern void tss_delete (tss_t __tss_id); - -__END_DECLS - -#endif /* _THREADS_H */ diff --git a/sysdeps/hurd/stdc-predef.h b/sysdeps/hurd/stdc-predef.h new file mode 100644 index 0000000..4c11188 --- /dev/null +++ b/sysdeps/hurd/stdc-predef.h @@ -0,0 +1,63 @@ +/* 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 _STDC_PREDEF_H +#define _STDC_PREDEF_H 1 + +/* This header is separate from features.h so that the compiler can + include it implicitly at the start of every compilation. It must + not itself include or any other header that includes + because the implicit include comes before any feature + test macros that may be defined in a source file before it first + explicitly includes a system header. GCC knows the name of this + header in order to preinclude it. */ + +/* glibc's intent is to support the IEC 559 math functionality, real + and complex. If the GCC (4.9 and later) predefined macros + specifying compiler intent are available, use them to determine + whether the overall intent is to support these features; otherwise, + presume an older compiler has intent to support these features and + define these macros by default. */ + +#ifdef __GCC_IEC_559 +# if __GCC_IEC_559 > 0 +# define __STDC_IEC_559__ 1 +# endif +#else +# define __STDC_IEC_559__ 1 +#endif + +#ifdef __GCC_IEC_559_COMPLEX +# if __GCC_IEC_559_COMPLEX > 0 +# define __STDC_IEC_559_COMPLEX__ 1 +# endif +#else +# define __STDC_IEC_559_COMPLEX__ 1 +#endif + +/* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is + synchronized with ISO/IEC 10646:2017, fifth edition, plus + the following additions from Amendment 1 to the fifth edition: + - 56 emoji characters + - 285 hentaigana + - 3 additional Zanabazar Square characters */ +#define __STDC_ISO_10646__ 201706L + +/* We do not support C11 . */ +#define __STDC_NO_THREADS__ 1 + +#endif diff --git a/sysdeps/nptl/threads.h b/sysdeps/nptl/threads.h index 1090612..9800f93 100644 --- a/sysdeps/nptl/threads.h +++ b/sysdeps/nptl/threads.h @@ -1 +1,207 @@ -#include +/* 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 +#include + +#ifndef __cplusplus +# define thread_local _Thread_local +#endif + +#define TSS_DTOR_ITERATIONS 4 +typedef unsigned int tss_t; +typedef void (*tss_dtor_t) (void*); + +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 +}; + +/* Mutex types. */ +enum +{ + mtx_plain = 0, + mtx_recursive = 1, + mtx_timed = 2 +}; + +typedef struct +{ + int __data __ONCE_ALIGNMENT; +} once_flag; +#define ONCE_FLAG_INIT { 0 } + +typedef union +{ + char __size[__SIZEOF_PTHREAD_MUTEX_T]; + long int __align __LOCK_ALIGNMENT; +} mtx_t; + +typedef union +{ + char __size[__SIZEOF_PTHREAD_COND_T]; + __extension__ long long int __align __LOCK_ALIGNMENT; +} cnd_t; + +/* 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 + (it 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 + + +/* Mutex functions. */ + +/* Creates a new mutex object with type __TYPE. If successful the new + object is pointed by __MUTEX. */ +extern int mtx_init (mtx_t *__mutex, int __type); + +/* Block the current thread until the mutex pointed to by __MUTEX is + unlocked. In that case current thread will not be blocked. */ +extern int mtx_lock (mtx_t *__mutex); + +/* Block the current thread until the mutex pointed by __MUTEX is unlocked + or time pointed by __TIME_POINT is reached. In case the mutex is unlock, + the current thread will not be blocked. */ +extern int mtx_timedlock (mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); + +/* Try to lock the mutex pointed by __MUTEX without blocking. If the mutex + is free the current threads takes control of it, otherwise it returns + immediately. */ +extern int mtx_trylock (mtx_t *__mutex); + +/* Unlock the mutex pointed by __MUTEX. It may potentially awake other + threads waiting on this mutex. */ +extern int mtx_unlock (mtx_t *__mutex); + +/* Destroy the mutex object pointed by __MUTEX. */ +extern void mtx_destroy (mtx_t *__mutex); + + +/* Call function __FUNC exactly once, even if invoked from several threads. + All calls must be made with the same __FLAGS object. */ +extern void call_once (once_flag *__flag, void (*__func)(void)); + + +/* Condition variable functions. */ + +/* Initialize new condition variable pointed by __COND. */ +extern int cnd_init (cnd_t *__cond); + +/* Unblock one thread that currently waits on condition variable pointed + by __COND. */ +extern int cnd_signal (cnd_t *__cond); + +/* Unblock all threads currently waiting on condition variable pointed by + __COND. */ +extern int cnd_broadcast (cnd_t *__cond); + +/* Block current thread on the condition variable pointed by __COND. */ +extern int cnd_wait (cnd_t *__cond, mtx_t *__mutex); + +/* Block current thread on the condition variable until condition variable + pointed by __COND is signaled or time pointed by __TIME_POINT is + reached. */ +extern int cnd_timedwait (cnd_t *__restrict __cond, + mtx_t *__restrict __mutex, + const struct timespec *__restrict __time_point); + +/* Destroy condition variable pointed by __cond and free all of its + resources. */ +extern void cnd_destroy (cnd_t *__COND); + + +/* Thread specific storage functions. */ + +/* Create new thread-specific storage key and stores it in the object pointed + by __TSS_ID. If __DESTRUCTOR is not NULL, the function will be called when + the thread terminates. */ +extern int tss_create (tss_t *__tss_id, tss_dtor_t __destructor); + +/* Return the value held in thread-specific storage for the current thread + identified by __TSS_ID. */ +extern void *tss_get (tss_t __tss_id); + +/* Sets the value of the thread-specific storage identified by __TSS_ID for + the current thread to __VAL. */ +extern int tss_set (tss_t __tss_id, void *__val); + +/* Destroys the thread-specific storage identified by __TSS_ID. The + destructor is not called until thrd_exit is called. */ +extern void tss_delete (tss_t __tss_id); + +__END_DECLS + +#endif /* _THREADS_H */