Fix C11 conformance issues

Message ID 1532526205-5708-1-git-send-email-adhemerval.zanella@linaro.org
State Accepted
Commit 9faaf9385034ac71f308643de1afc91b5dd731aa
Headers show
Series
  • Fix C11 conformance issues
Related show

Commit Message

Adhemerval Zanella July 25, 2018, 1:43 p.m.
Remove conformace assumption of NPTL implementation for ISO C threads
and revert wrong libcrypt addition on linknamespace-libs-XPG4.

The i686-gnu target now shows two new conformance failures:

FAIL: conform/ISO11/threads.h/conform
FAIL: conform/ISO11/threads.h/linknamespace

It is expected due missing HTL ISO C threads support and both conformance
.out files indicates the reason ("#error "HTL does not implement ISO C
threads").

Checked on i686-linux-gnu and i686-gnu.

	* include/threads.h: Move to ...
	* sysdeps/nptl/threads.h: ... here.
	* sysdeps/htl/threads.h: New file.
	* conform/Makefile (linknamespace-libs-ISO11): Use
	static-thread-library instead of linking libpthread.
	(linknamespace-libs-XPG4): Revert wrong libcrypt.a addition.
---
 ChangeLog                           | 9 +++++++++
 conform/Makefile                    | 5 ++---
 sysdeps/htl/threads.h               | 1 +
 {include => sysdeps/nptl}/threads.h | 0
 4 files changed, 12 insertions(+), 3 deletions(-)
 create mode 100644 sysdeps/htl/threads.h
 rename {include => sysdeps/nptl}/threads.h (100%)

-- 
2.7.4

Comments

Samuel Thibault July 25, 2018, 1:51 p.m. | #1
Adhemerval Zanella, le mer. 25 juil. 2018 10:43:25 -0300, a ecrit:
> It is expected due missing HTL ISO C threads support and both conformance

> .out files indicates the reason ("#error "HTL does not implement ISO C

> threads").


I thought the ISO C threads were just a layer on top of the POSIX
threads, can't it be used on top of HTL too?

I'm not saying we should aim for this in 2.28, just wondering.

Samuel
Carlos O'Donell July 25, 2018, 2:32 p.m. | #2
On 07/25/2018 09:43 AM, Adhemerval Zanella wrote:
> Remove conformace assumption of NPTL implementation for ISO C threads

> and revert wrong libcrypt addition on linknamespace-libs-XPG4.

> 

> The i686-gnu target now shows two new conformance failures:

> 

> FAIL: conform/ISO11/threads.h/conform

> FAIL: conform/ISO11/threads.h/linknamespace

> 

> It is expected due missing HTL ISO C threads support and both conformance

> .out files indicates the reason ("#error "HTL does not implement ISO C

> threads").

> 

> Checked on i686-linux-gnu and i686-gnu.

> 

> 	* include/threads.h: Move to ...

> 	* sysdeps/nptl/threads.h: ... here.

> 	* sysdeps/htl/threads.h: New file.

> 	* conform/Makefile (linknamespace-libs-ISO11): Use

> 	static-thread-library instead of linking libpthread.

> 	(linknamespace-libs-XPG4): Revert wrong libcrypt.a addition.


OK for 2.28.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>


> ---

>  ChangeLog                           | 9 +++++++++

>  conform/Makefile                    | 5 ++---

>  sysdeps/htl/threads.h               | 1 +

>  {include => sysdeps/nptl}/threads.h | 0

>  4 files changed, 12 insertions(+), 3 deletions(-)

>  create mode 100644 sysdeps/htl/threads.h

>  rename {include => sysdeps/nptl}/threads.h (100%)

> 

> diff --git a/conform/Makefile b/conform/Makefile

> index a0ab70e..d430931 100644

> --- a/conform/Makefile

> +++ b/conform/Makefile

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

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

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

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

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

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

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

> +			   $(static-thread-library)


OK, uses static-thread-library.

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


OK, fixes libcrypt issue.

>  linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)

>  linknamespace-libs-POSIX = $(linknamespace-libs-thr)

>  linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)

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

> new file mode 100644

> index 0000000..3c04fbc

> --- /dev/null

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

> @@ -0,0 +1 @@

> +#error "HTL does not implement ISO C threads"


OK.

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

> similarity index 100%

> rename from include/threads.h

> rename to sysdeps/nptl/threads.h

>
Adhemerval Zanella July 25, 2018, 3:01 p.m. | #3
On 25/07/2018 10:51, Samuel Thibault wrote:
> Adhemerval Zanella, le mer. 25 juil. 2018 10:43:25 -0300, a ecrit:

>> It is expected due missing HTL ISO C threads support and both conformance

>> .out files indicates the reason ("#error "HTL does not implement ISO C

>> threads").

> 

> I thought the ISO C threads were just a layer on top of the POSIX

> threads, can't it be used on top of HTL too?

> 

> I'm not saying we should aim for this in 2.28, just wondering.

> 

> Samuel

> 


Currently implementation is based on POSIX internally, although it
does not require to be (Florian has suggested we might use a more
streamline implementation in the future).

However you will need to correctly tie the HTL required types with
ISO C threads without adding namespace or linkspace pollution. For
NPTL we refactored the required information on pthreadtypes-arch.h,
so to make threads.h generic HTL will need to provide a similar 
implementation (it also defines any internal structure alignment
requirement, but afaiu HTL does not have any arch-specific constraint
so far).

I am not familiar with HTL internals, but ISO C required some NPTL
internal adjustments:

  - the function pointer of the ISO C thread thrd_start start
    function has a different signature of pthread_create
    (int (*thrd_start_t) (void*) for ISO C and
    void *(*start_routine) (void *) for POSIX).

  - thrd_sleep call the syscall directly to avoid to handle the 
    expected C11 states.  It would require to add new nanosleep
    wrapper with expected behaviour.

  - thrd_yield also call the syscall directly, but adding a
    wrapper would be easier since there is no need to handle
    the return code.

However I think it quite feasible for 2.29 to add ISO C threads 
Hurd/HTL support.
Joseph Myers July 25, 2018, 3:40 p.m. | #4
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.)

-- 
Joseph S. Myers
joseph@codesourcery.com
Joseph Myers July 25, 2018, 3:42 p.m. | #5
On Wed, 25 Jul 2018, Adhemerval Zanella wrote:

> I am not familiar with HTL internals, but ISO C required some NPTL

> internal adjustments:


- The C11 threads functions call __pthread_* internally, so all those 
__pthread_* names needed to exist and, where they called POSIX functions 
internally, they needed to be made to call __* names for those functions 
where that wasn't previously necessary for POSIX namespace reasons.

-- 
Joseph S. Myers
joseph@codesourcery.com
Joseph Myers July 25, 2018, 3:44 p.m. | #6
On Wed, 25 Jul 2018, 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?


(The normal convention for a wrapper not in include would be for it to be 
in sysdeps/nptl/include/ rather than directly in sysdeps/nptl/.)

-- 
Joseph S. Myers
joseph@codesourcery.com
Joseph Myers July 25, 2018, 3:54 p.m. | #7
On Wed, 25 Jul 2018, 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 tested a build as of commit 08ac6bed146c0546d63163ac0d42c9a35880412d.  
This patch has resulted in the wrong threads.h being installed, i.e. 
usr/include/threads.h is now the wrapper that just does #include 
<nptl/threads.h>, which obviously won't work for an installed header.

I think you need to put the real threads.h header in sysdeps/nptl/, not 
the wrapper (with a view to the Hurd work moving both the header, and the 
C11 threads implementation and tests, to sysdeps/pthread/ or some such 
shared location).

-- 
Joseph S. Myers
joseph@codesourcery.com
Florian Weimer July 25, 2018, 5:08 p.m. | #8
On 07/25/2018 03:43 PM, Adhemerval Zanella wrote:
>   linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \

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

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

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

> +			   $(static-thread-library)


I've just realized this:

Linking with the static thread library obscures linknamespace issues in 
libc.a for symbols which are also defined in libpthread.a.  So this 
change is a bit questionable.

Thanks,
Florian
Joseph Myers July 25, 2018, 5:18 p.m. | #9
On Wed, 25 Jul 2018, Florian Weimer wrote:

> On 07/25/2018 03:43 PM, Adhemerval Zanella wrote:

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

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

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

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

> > +			   $(static-thread-library)

> 

> I've just realized this:

> 

> Linking with the static thread library obscures linknamespace issues in libc.a

> for symbols which are also defined in libpthread.a.  So this change is a bit

> questionable.


The linknamespace code looks at every definition of a strong undefined 
symbol being resolved, not just the definition in a particular library.

-- 
Joseph S. Myers
joseph@codesourcery.com
Florian Weimer July 25, 2018, 5:24 p.m. | #10
On 07/25/2018 07:18 PM, Joseph Myers wrote:
> On Wed, 25 Jul 2018, Florian Weimer wrote:

> 

>> On 07/25/2018 03:43 PM, Adhemerval Zanella wrote:

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

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

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

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

>>> +			   $(static-thread-library)

>>

>> I've just realized this:

>>

>> Linking with the static thread library obscures linknamespace issues in libc.a

>> for symbols which are also defined in libpthread.a.  So this change is a bit

>> questionable.

> 

> The linknamespace code looks at every definition of a strong undefined

> symbol being resolved, not just the definition in a particular library.


So there is not a problem after all?

What seems to be a problem is that libpthread.a must now be C11-clean 
for its C11 symbols (which is currently not the case on Hurd).  But 
fixing that is probably not a bad idea anyway.

Florian
Joseph Myers July 25, 2018, 5:47 p.m. | #11
On Wed, 25 Jul 2018, Florian Weimer wrote:

> On 07/25/2018 07:18 PM, Joseph Myers wrote:

> > On Wed, 25 Jul 2018, Florian Weimer wrote:

> > 

> > > On 07/25/2018 03:43 PM, Adhemerval Zanella wrote:

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

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

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

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

> > > > +			   $(static-thread-library)

> > > 

> > > I've just realized this:

> > > 

> > > Linking with the static thread library obscures linknamespace issues in

> > > libc.a

> > > for symbols which are also defined in libpthread.a.  So this change is a

> > > bit

> > > questionable.

> > 

> > The linknamespace code looks at every definition of a strong undefined

> > symbol being resolved, not just the definition in a particular library.

> 

> So there is not a problem after all?


I don't think there's any problem with that part of the patch.

> What seems to be a problem is that libpthread.a must now be C11-clean for its

> C11 symbols (which is currently not the case on Hurd).  But fixing that is

> probably not a bad idea anyway.


Yes, if libpthread is used to provide some C11 symbols, it needs to be 
C11-clean for all the C11 symbols it provides (including those also 
present in libc).

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella July 25, 2018, 6:28 p.m. | #12
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.

---

[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  <threads.h>.
-   Copyright (C) 2018 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _THREADS_H
-#define _THREADS_H	1
-
-#include <features.h>
-#include <time.h>
-
-__BEGIN_DECLS
-
-#include <bits/pthreadtypes-arch.h>
-#include <bits/types/struct_timespec.h>
-
-#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
+   <http://www.gnu.org/licenses/>.  */
+
+#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 <features.h> or any other header that includes
+   <features.h> 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 <threads.h>.  */
+#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 <nptl/threads.h>
+/* ISO C11 Standard: 7.26 - Thread support library  <threads.h>.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _THREADS_H
+#define _THREADS_H	1
+
+#include <features.h>
+#include <time.h>
+
+__BEGIN_DECLS
+
+#include <bits/pthreadtypes-arch.h>
+#include <bits/types/struct_timespec.h>
+
+#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 */
Adhemerval Zanella July 25, 2018, 6:41 p.m. | #13
On 25/07/2018 12:42, Joseph Myers wrote:
> On Wed, 25 Jul 2018, Adhemerval Zanella wrote:

> 

>> I am not familiar with HTL internals, but ISO C required some NPTL

>> internal adjustments:

> 

> - The C11 threads functions call __pthread_* internally, so all those 

> __pthread_* names needed to exist and, where they called POSIX functions 

> internally, they needed to be made to call __* names for those functions 

> where that wasn't previously necessary for POSIX namespace reasons.

> 


So summarize and assuming the fix for the stdc-predef.h for HURD [1], 
ISO C threads support for HTL would require:

  - Add the required __pthread_*  alias called from C11 threads and
    also fix any internal possible linkspace name issue by calling
    libpthread __* names.

  - Correctly tie the HTL required types with ISO C threads without 
    adding namespace or linkspace pollution by adding a platform
    pthreadtypes-arch.h implementation (not sure if it would require
    arch-specific ones since HURD since to support only i686).

  - Check if HTL requires some handling of the function pointer 
    mismatch between ISO C thread thrd_start start and pthread_create.

  - Add a wrapper to nanosleep to return syscall return code directly
    to use on thrd_sleep.

  - Call __sched_yield in thrd_yield.

  - Remove hurd specific stdc-predef.h and htl threads.h and make
    threads.h the generic one.

[1] https://sourceware.org/ml/libc-alpha/2018-07/msg00835.html
Florian Weimer July 25, 2018, 8:03 p.m. | #14
On 07/25/2018 07:47 PM, Joseph Myers wrote:

>> What seems to be a problem is that libpthread.a must now be C11-clean for its

>> C11 symbols (which is currently not the case on Hurd).  But fixing that is

>> probably not a bad idea anyway.

> 

> Yes, if libpthread is used to provide some C11 symbols, it needs to be

> C11-clean for all the C11 symbols it provides (including those also

> present in libc).


So I think we need something like this.  It resolves the new 
linknamespace failures for me.

Thanks,
Florian
Subject: [PATCH] htl: Use weak aliases for public symbols
To: libc-alpha@sourceware.org

Strong definitions of flockfile, funlockfile, ftrylockfile can conflict
with application symbols when linking statically.

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

	* htl/lockfile.c (flockfile, funlockfile, ftrylockfile): Use weak
	aliases for symbols not in the implementation namespace.

diff --git a/htl/lockfile.c b/htl/lockfile.c
index 7828d47dae..1d0ab88b13 100644
--- a/htl/lockfile.c
+++ b/htl/lockfile.c
@@ -53,8 +53,8 @@ int _IO_ftrylockfile (FILE *)
      __attribute__ ((alias ("_cthreads_ftrylockfile")));
 
 void flockfile (FILE *)
-     __attribute__ ((alias ("_cthreads_flockfile")));
+     __attribute__ ((weak, alias ("_cthreads_flockfile")));
 void funlockfile (FILE *)
-     __attribute__ ((alias ("_cthreads_funlockfile")));
+     __attribute__ ((weak, alias ("_cthreads_funlockfile")));
 int ftrylockfile (FILE *)
-     __attribute__ ((alias ("_cthreads_ftrylockfile")));
+     __attribute__ ((weak, alias ("_cthreads_ftrylockfile")));
Joseph Myers July 25, 2018, 8:18 p.m. | #15
On Wed, 25 Jul 2018, Adhemerval Zanella wrote:

> 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.


This patch is OK.  The handling of precompiled headers in GCC is very 
fragile with regard to implicitly preincluded files and if stdc-predef.h 
were to include another header, there would be a significant chance of 
this breaking PCH.

-- 
Joseph S. Myers
joseph@codesourcery.com
Joseph Myers July 25, 2018, 8:20 p.m. | #16
On Wed, 25 Jul 2018, Adhemerval Zanella wrote:

> So summarize and assuming the fix for the stdc-predef.h for HURD [1], 

> ISO C threads support for HTL would require:

> 

>   - Add the required __pthread_*  alias called from C11 threads and

>     also fix any internal possible linkspace name issue by calling

>     libpthread __* names.

> 

>   - Correctly tie the HTL required types with ISO C threads without 

>     adding namespace or linkspace pollution by adding a platform

>     pthreadtypes-arch.h implementation (not sure if it would require

>     arch-specific ones since HURD since to support only i686).

> 

>   - Check if HTL requires some handling of the function pointer 

>     mismatch between ISO C thread thrd_start start and pthread_create.

> 

>   - Add a wrapper to nanosleep to return syscall return code directly

>     to use on thrd_sleep.

> 

>   - Call __sched_yield in thrd_yield.

> 

>   - Remove hurd specific stdc-predef.h and htl threads.h and make

>     threads.h the generic one.


- Move all the relevant implementation files and tests and associated 
makefile logic out of nptl/ into a shared directory such as 
sysdeps/pthread/ so that they get built for Hurd as well.

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella July 25, 2018, 8:23 p.m. | #17
On 25/07/2018 17:20, Joseph Myers wrote:
> On Wed, 25 Jul 2018, Adhemerval Zanella wrote:

> 

>> So summarize and assuming the fix for the stdc-predef.h for HURD [1], 

>> ISO C threads support for HTL would require:

>>

>>   - Add the required __pthread_*  alias called from C11 threads and

>>     also fix any internal possible linkspace name issue by calling

>>     libpthread __* names.

>>

>>   - Correctly tie the HTL required types with ISO C threads without 

>>     adding namespace or linkspace pollution by adding a platform

>>     pthreadtypes-arch.h implementation (not sure if it would require

>>     arch-specific ones since HURD since to support only i686).

>>

>>   - Check if HTL requires some handling of the function pointer 

>>     mismatch between ISO C thread thrd_start start and pthread_create.

>>

>>   - Add a wrapper to nanosleep to return syscall return code directly

>>     to use on thrd_sleep.

>>

>>   - Call __sched_yield in thrd_yield.

>>

>>   - Remove hurd specific stdc-predef.h and htl threads.h and make

>>     threads.h the generic one.

> 

> - Move all the relevant implementation files and tests and associated 

> makefile logic out of nptl/ into a shared directory such as 

> sysdeps/pthread/ so that they get built for Hurd as well.

> 


Right, I will try to spend some cycles for 2.29.
Carlos O'Donell July 25, 2018, 8:25 p.m. | #18
On 07/25/2018 04:03 PM, Florian Weimer wrote:
> Strong definitions of flockfile, funlockfile, ftrylockfile can conflict

> with application symbols when linking statically.


This looks OK to me for 2.28.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>


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

> 

> 	* htl/lockfile.c (flockfile, funlockfile, ftrylockfile): Use weak

> 	aliases for symbols not in the implementation namespace.

> 

> diff --git a/htl/lockfile.c b/htl/lockfile.c

> index 7828d47dae..1d0ab88b13 100644

> --- a/htl/lockfile.c

> +++ b/htl/lockfile.c

> @@ -53,8 +53,8 @@ int _IO_ftrylockfile (FILE *)

>       __attribute__ ((alias ("_cthreads_ftrylockfile")));

>  

>  void flockfile (FILE *)

> -     __attribute__ ((alias ("_cthreads_flockfile")));

> +     __attribute__ ((weak, alias ("_cthreads_flockfile")));

>  void funlockfile (FILE *)

> -     __attribute__ ((alias ("_cthreads_funlockfile")));

> +     __attribute__ ((weak, alias ("_cthreads_funlockfile")));

>  int ftrylockfile (FILE *)

> -     __attribute__ ((alias ("_cthreads_ftrylockfile")));

> +     __attribute__ ((weak, alias ("_cthreads_ftrylockfile")));


OK.

c.
Carlos O'Donell July 25, 2018, 8:28 p.m. | #19
On 07/25/2018 02:28 PM, Adhemerval Zanella wrote:
> [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.


This is OK for 2.28. It is just movement of the normal threads.h to nptl
(not generic anymore), and the new stdc-predef.h for hurd. With the other
fixes that you and Joseph discussed coming in 2.29 or later.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>


> ---

>  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  <threads.h>.

> -   Copyright (C) 2018 Free Software Foundation, Inc.

> -   This file is part of the GNU C Library.

> -

> -   The GNU C Library is free software; you can redistribute it and/or

> -   modify it under the terms of the GNU Lesser General Public

> -   License as published by the Free Software Foundation; either

> -   version 2.1 of the License, or (at your option) any later version.

> -

> -   The GNU C Library is distributed in the hope that it will be useful,

> -   but WITHOUT ANY WARRANTY; without even the implied warranty of

> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

> -   Lesser General Public License for more details.

> -

> -   You should have received a copy of the GNU Lesser General Public

> -   License along with the GNU C Library; if not, see

> -   <http://www.gnu.org/licenses/>.  */

> -

> -#ifndef _THREADS_H

> -#define _THREADS_H	1

> -

> -#include <features.h>

> -#include <time.h>

> -

> -__BEGIN_DECLS

> -

> -#include <bits/pthreadtypes-arch.h>

> -#include <bits/types/struct_timespec.h>

> -

> -#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

> +   <http://www.gnu.org/licenses/>.  */

> +

> +#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 <features.h> or any other header that includes

> +   <features.h> 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 <threads.h>.  */

> +#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 <nptl/threads.h>

> +/* ISO C11 Standard: 7.26 - Thread support library  <threads.h>.

> +   Copyright (C) 2018 Free Software Foundation, Inc.

> +   This file is part of the GNU C Library.

> +

> +   The GNU C Library is free software; you can redistribute it and/or

> +   modify it under the terms of the GNU Lesser General Public

> +   License as published by the Free Software Foundation; either

> +   version 2.1 of the License, or (at your option) any later version.

> +

> +   The GNU C Library is distributed in the hope that it will be useful,

> +   but WITHOUT ANY WARRANTY; without even the implied warranty of

> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

> +   Lesser General Public License for more details.

> +

> +   You should have received a copy of the GNU Lesser General Public

> +   License along with the GNU C Library; if not, see

> +   <http://www.gnu.org/licenses/>.  */

> +

> +#ifndef _THREADS_H

> +#define _THREADS_H	1

> +

> +#include <features.h>

> +#include <time.h>

> +

> +__BEGIN_DECLS

> +

> +#include <bits/pthreadtypes-arch.h>

> +#include <bits/types/struct_timespec.h>

> +

> +#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 */

>

Patch

diff --git a/conform/Makefile b/conform/Makefile
index a0ab70e..d430931 100644
--- a/conform/Makefile
+++ b/conform/Makefile
@@ -197,9 +197,8 @@  linknamespace-libs-xsi = $(linknamespace-libs-posix)
 linknamespace-libs-ISO = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO99 = $(linknamespace-libs-isoc)
 linknamespace-libs-ISO11 = $(linknamespace-libs-isoc) \
-			   $(common-objpfx)nptl/libpthread.a
-linknamespace-libs-XPG4 = $(linknamespace-libs-isoc) \
-			  $(common-objpfx)crypt/libcrypt.a
+			   $(static-thread-library)
+linknamespace-libs-XPG4 = $(linknamespace-libs-isoc)
 linknamespace-libs-XPG42 = $(linknamespace-libs-XPG4)
 linknamespace-libs-POSIX = $(linknamespace-libs-thr)
 linknamespace-libs-UNIX98 = $(linknamespace-libs-xsi)
diff --git a/sysdeps/htl/threads.h b/sysdeps/htl/threads.h
new file mode 100644
index 0000000..3c04fbc
--- /dev/null
+++ b/sysdeps/htl/threads.h
@@ -0,0 +1 @@ 
+#error "HTL does not implement ISO C threads"
diff --git a/include/threads.h b/sysdeps/nptl/threads.h
similarity index 100%
rename from include/threads.h
rename to sysdeps/nptl/threads.h