mbox series

[v8,0/8] Add support for ISO C threads.h

Message ID 1517591084-11347-1-git-send-email-adhemerval.zanella@linaro.org
Headers show
Series Add support for ISO C threads.h | expand

Message

Adhemerval Zanella Netto Feb. 2, 2018, 5:04 p.m. UTC
This is a new update for C11 threads support based on my previous [1]
version.  The main changes from previous version are:
 
  - Rebase against 2.28.

  - Add RISCV abilist symbols.
 
  - Adjusted copyright dates for 2018.
 
  - Remove some redundant comments.
 
I tested this without regression with a full make/check on
x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
powerpc-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf,
sparc64-linux-gnu, and sparcv9-linux-gnu.
 
[1] https://sourceware.org/ml/libc-alpha/2017-09/msg00871.html

Adhemerval Zanella (7):
  nptl: Add C11 threads thrd_* functions
  nptl: Add C11 threads mtx_* functions
  nptl: Add C11 threads call_once functions
  nptl: Add C11 threads cnd_* functions
  nptl: Add C11 threads tss_* functions
  nptl: Add abilist symbols for C11 threads
  nptl: Add test cases for ISO C11 threads

Juan Manuel Torres Palma (1):
  Add manual documentation for threads.h

 ChangeLog                                          | 175 ++++++++++
 conform/Makefile                                   |   7 +-
 conform/data/threads.h-data                        |  57 ++++
 include/stdc-predef.h                              |   3 -
 manual/Makefile                                    |   2 +-
 manual/isothreads.texi                             | 355 +++++++++++++++++++++
 nptl/Makefile                                      |  15 +-
 nptl/Versions                                      |   9 +
 nptl/call_once.c                                   |  31 ++
 nptl/cnd_broadcast.c                               |  26 ++
 nptl/cnd_destroy.c                                 |  26 ++
 nptl/cnd_init.c                                    |  32 ++
 nptl/cnd_signal.c                                  |  26 ++
 nptl/cnd_timedwait.c                               |  29 ++
 nptl/cnd_wait.c                                    |  27 ++
 nptl/descr.h                                       |   2 +
 nptl/mtx_destroy.c                                 |  26 ++
 nptl/mtx_init.c                                    |  52 +++
 nptl/mtx_lock.c                                    |  26 ++
 nptl/mtx_timedlock.c                               |  28 ++
 nptl/mtx_trylock.c                                 |  26 ++
 nptl/mtx_unlock.c                                  |  26 ++
 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 ++
 nptl/tss_create.c                                  |  28 ++
 nptl/tss_delete.c                                  |  25 ++
 nptl/tss_get.c                                     |  25 ++
 nptl/tss_set.c                                     |  26 ++
 nptl/tst-call-once.c                               |  66 ++++
 nptl/tst-cnd-basic.c                               |  68 ++++
 nptl/tst-cnd-broadcast.c                           |  83 +++++
 nptl/tst-cnd-timedwait.c                           |  70 ++++
 nptl/tst-mtx-basic.c                               |  73 +++++
 nptl/tst-mtx-recursive.c                           |  45 +++
 nptl/tst-mtx-timedlock.c                           |  98 ++++++
 nptl/tst-mtx-trylock.c                             |  90 ++++++
 nptl/tst-thrd-detach.c                             |  52 +++
 nptl/tst-thrd-sleep.c                              |  51 +++
 nptl/tst-tss-basic.c                               |  75 +++++
 sysdeps/nptl/threads.h                             | 200 ++++++++++++
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist |  26 ++
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist   |  26 ++
 sysdeps/unix/sysv/linux/arm/libpthread.abilist     |  26 ++
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist    |  26 ++
 sysdeps/unix/sysv/linux/i386/libpthread.abilist    |  26 ++
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |  26 ++
 .../sysv/linux/m68k/coldfire/libpthread.abilist    |  26 ++
 .../unix/sysv/linux/m68k/m680x0/libpthread.abilist |  26 ++
 .../unix/sysv/linux/microblaze/libpthread.abilist  |  26 ++
 .../unix/sysv/linux/mips/mips32/libpthread.abilist |  26 ++
 .../unix/sysv/linux/mips/mips64/libpthread.abilist |  26 ++
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist   |  26 ++
 .../linux/powerpc/powerpc32/libpthread.abilist     |  26 ++
 .../linux/powerpc/powerpc64/libpthread-le.abilist  |  26 ++
 .../linux/powerpc/powerpc64/libpthread.abilist     |  26 ++
 .../unix/sysv/linux/riscv/rv64/libpthread.abilist  |  26 ++
 .../sysv/linux/s390/s390-32/libpthread.abilist     |  26 ++
 .../sysv/linux/s390/s390-64/libpthread.abilist     |  26 ++
 sysdeps/unix/sysv/linux/sh/libpthread.abilist      |  26 ++
 .../sysv/linux/sparc/sparc32/libpthread.abilist    |  26 ++
 .../sysv/linux/sparc/sparc64/libpthread.abilist    |  26 ++
 .../sysv/linux/tile/tilegx32/libpthread.abilist    |  26 ++
 .../sysv/linux/tile/tilegx64/libpthread.abilist    |  26 ++
 .../unix/sysv/linux/x86_64/64/libpthread.abilist   |  26 ++
 .../unix/sysv/linux/x86_64/x32/libpthread.abilist  |  26 ++
 74 files changed, 3011 insertions(+), 12 deletions(-)
 create mode 100644 conform/data/threads.h-data
 create mode 100644 manual/isothreads.texi
 create mode 100644 nptl/call_once.c
 create mode 100644 nptl/cnd_broadcast.c
 create mode 100644 nptl/cnd_destroy.c
 create mode 100644 nptl/cnd_init.c
 create mode 100644 nptl/cnd_signal.c
 create mode 100644 nptl/cnd_timedwait.c
 create mode 100644 nptl/cnd_wait.c
 create mode 100644 nptl/mtx_destroy.c
 create mode 100644 nptl/mtx_init.c
 create mode 100644 nptl/mtx_lock.c
 create mode 100644 nptl/mtx_timedlock.c
 create mode 100644 nptl/mtx_trylock.c
 create mode 100644 nptl/mtx_unlock.c
 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 nptl/tss_create.c
 create mode 100644 nptl/tss_delete.c
 create mode 100644 nptl/tss_get.c
 create mode 100644 nptl/tss_set.c
 create mode 100644 nptl/tst-call-once.c
 create mode 100644 nptl/tst-cnd-basic.c
 create mode 100644 nptl/tst-cnd-broadcast.c
 create mode 100644 nptl/tst-cnd-timedwait.c
 create mode 100644 nptl/tst-mtx-basic.c
 create mode 100644 nptl/tst-mtx-recursive.c
 create mode 100644 nptl/tst-mtx-timedlock.c
 create mode 100644 nptl/tst-mtx-trylock.c
 create mode 100644 nptl/tst-thrd-detach.c
 create mode 100644 nptl/tst-thrd-sleep.c
 create mode 100644 nptl/tst-tss-basic.c
 create mode 100644 sysdeps/nptl/threads.h

-- 
2.7.4

Comments

Adhemerval Zanella Netto June 27, 2018, 1:39 p.m. UTC | #1
Ping, do we still want this for 2.28 release?

On 02/02/2018 15:04, Adhemerval Zanella wrote:
> This is a new update for C11 threads support based on my previous [1]

> version.  The main changes from previous version are:

>  

>   - Rebase against 2.28.

> 

>   - Add RISCV abilist symbols.

>  

>   - Adjusted copyright dates for 2018.

>  

>   - Remove some redundant comments.

>  

> I tested this without regression with a full make/check on

> x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,

> powerpc-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf,

> sparc64-linux-gnu, and sparcv9-linux-gnu.

>  

> [1] https://sourceware.org/ml/libc-alpha/2017-09/msg00871.html

> 

> Adhemerval Zanella (7):

>   nptl: Add C11 threads thrd_* functions

>   nptl: Add C11 threads mtx_* functions

>   nptl: Add C11 threads call_once functions

>   nptl: Add C11 threads cnd_* functions

>   nptl: Add C11 threads tss_* functions

>   nptl: Add abilist symbols for C11 threads

>   nptl: Add test cases for ISO C11 threads

> 

> Juan Manuel Torres Palma (1):

>   Add manual documentation for threads.h

> 

>  ChangeLog                                          | 175 ++++++++++

>  conform/Makefile                                   |   7 +-

>  conform/data/threads.h-data                        |  57 ++++

>  include/stdc-predef.h                              |   3 -

>  manual/Makefile                                    |   2 +-

>  manual/isothreads.texi                             | 355 +++++++++++++++++++++

>  nptl/Makefile                                      |  15 +-

>  nptl/Versions                                      |   9 +

>  nptl/call_once.c                                   |  31 ++

>  nptl/cnd_broadcast.c                               |  26 ++

>  nptl/cnd_destroy.c                                 |  26 ++

>  nptl/cnd_init.c                                    |  32 ++

>  nptl/cnd_signal.c                                  |  26 ++

>  nptl/cnd_timedwait.c                               |  29 ++

>  nptl/cnd_wait.c                                    |  27 ++

>  nptl/descr.h                                       |   2 +

>  nptl/mtx_destroy.c                                 |  26 ++

>  nptl/mtx_init.c                                    |  52 +++

>  nptl/mtx_lock.c                                    |  26 ++

>  nptl/mtx_timedlock.c                               |  28 ++

>  nptl/mtx_trylock.c                                 |  26 ++

>  nptl/mtx_unlock.c                                  |  26 ++

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

>  nptl/tss_create.c                                  |  28 ++

>  nptl/tss_delete.c                                  |  25 ++

>  nptl/tss_get.c                                     |  25 ++

>  nptl/tss_set.c                                     |  26 ++

>  nptl/tst-call-once.c                               |  66 ++++

>  nptl/tst-cnd-basic.c                               |  68 ++++

>  nptl/tst-cnd-broadcast.c                           |  83 +++++

>  nptl/tst-cnd-timedwait.c                           |  70 ++++

>  nptl/tst-mtx-basic.c                               |  73 +++++

>  nptl/tst-mtx-recursive.c                           |  45 +++

>  nptl/tst-mtx-timedlock.c                           |  98 ++++++

>  nptl/tst-mtx-trylock.c                             |  90 ++++++

>  nptl/tst-thrd-detach.c                             |  52 +++

>  nptl/tst-thrd-sleep.c                              |  51 +++

>  nptl/tst-tss-basic.c                               |  75 +++++

>  sysdeps/nptl/threads.h                             | 200 ++++++++++++

>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist |  26 ++

>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist   |  26 ++

>  sysdeps/unix/sysv/linux/arm/libpthread.abilist     |  26 ++

>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist    |  26 ++

>  sysdeps/unix/sysv/linux/i386/libpthread.abilist    |  26 ++

>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |  26 ++

>  .../sysv/linux/m68k/coldfire/libpthread.abilist    |  26 ++

>  .../unix/sysv/linux/m68k/m680x0/libpthread.abilist |  26 ++

>  .../unix/sysv/linux/microblaze/libpthread.abilist  |  26 ++

>  .../unix/sysv/linux/mips/mips32/libpthread.abilist |  26 ++

>  .../unix/sysv/linux/mips/mips64/libpthread.abilist |  26 ++

>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist   |  26 ++

>  .../linux/powerpc/powerpc32/libpthread.abilist     |  26 ++

>  .../linux/powerpc/powerpc64/libpthread-le.abilist  |  26 ++

>  .../linux/powerpc/powerpc64/libpthread.abilist     |  26 ++

>  .../unix/sysv/linux/riscv/rv64/libpthread.abilist  |  26 ++

>  .../sysv/linux/s390/s390-32/libpthread.abilist     |  26 ++

>  .../sysv/linux/s390/s390-64/libpthread.abilist     |  26 ++

>  sysdeps/unix/sysv/linux/sh/libpthread.abilist      |  26 ++

>  .../sysv/linux/sparc/sparc32/libpthread.abilist    |  26 ++

>  .../sysv/linux/sparc/sparc64/libpthread.abilist    |  26 ++

>  .../sysv/linux/tile/tilegx32/libpthread.abilist    |  26 ++

>  .../sysv/linux/tile/tilegx64/libpthread.abilist    |  26 ++

>  .../unix/sysv/linux/x86_64/64/libpthread.abilist   |  26 ++

>  .../unix/sysv/linux/x86_64/x32/libpthread.abilist  |  26 ++

>  74 files changed, 3011 insertions(+), 12 deletions(-)

>  create mode 100644 conform/data/threads.h-data

>  create mode 100644 manual/isothreads.texi

>  create mode 100644 nptl/call_once.c

>  create mode 100644 nptl/cnd_broadcast.c

>  create mode 100644 nptl/cnd_destroy.c

>  create mode 100644 nptl/cnd_init.c

>  create mode 100644 nptl/cnd_signal.c

>  create mode 100644 nptl/cnd_timedwait.c

>  create mode 100644 nptl/cnd_wait.c

>  create mode 100644 nptl/mtx_destroy.c

>  create mode 100644 nptl/mtx_init.c

>  create mode 100644 nptl/mtx_lock.c

>  create mode 100644 nptl/mtx_timedlock.c

>  create mode 100644 nptl/mtx_trylock.c

>  create mode 100644 nptl/mtx_unlock.c

>  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 nptl/tss_create.c

>  create mode 100644 nptl/tss_delete.c

>  create mode 100644 nptl/tss_get.c

>  create mode 100644 nptl/tss_set.c

>  create mode 100644 nptl/tst-call-once.c

>  create mode 100644 nptl/tst-cnd-basic.c

>  create mode 100644 nptl/tst-cnd-broadcast.c

>  create mode 100644 nptl/tst-cnd-timedwait.c

>  create mode 100644 nptl/tst-mtx-basic.c

>  create mode 100644 nptl/tst-mtx-recursive.c

>  create mode 100644 nptl/tst-mtx-timedlock.c

>  create mode 100644 nptl/tst-mtx-trylock.c

>  create mode 100644 nptl/tst-thrd-detach.c

>  create mode 100644 nptl/tst-thrd-sleep.c

>  create mode 100644 nptl/tst-tss-basic.c

>  create mode 100644 sysdeps/nptl/threads.h

>
Adhemerval Zanella Netto July 19, 2018, 5:46 p.m. UTC | #2
Florian, 

First thanks for the thoroughly review for c11 threads so far. I think it
has covered most the upcoming rough pieces.

Carlos, do you think we can squeeze this for 2.28? As you put private, I
also don't think we will get a 'pristine' implementation with optimal
object sizes without a refactor of internal nptl implementation.

On 27/06/2018 10:39, Adhemerval Zanella wrote:
> Ping, do we still want this for 2.28 release?

> 

> On 02/02/2018 15:04, Adhemerval Zanella wrote:

>> This is a new update for C11 threads support based on my previous [1]

>> version.  The main changes from previous version are:

>>  

>>   - Rebase against 2.28.

>>

>>   - Add RISCV abilist symbols.

>>  

>>   - Adjusted copyright dates for 2018.

>>  

>>   - Remove some redundant comments.

>>  

>> I tested this without regression with a full make/check on

>> x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,

>> powerpc-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf,

>> sparc64-linux-gnu, and sparcv9-linux-gnu.

>>  

>> [1] https://sourceware.org/ml/libc-alpha/2017-09/msg00871.html

>>

>> Adhemerval Zanella (7):

>>   nptl: Add C11 threads thrd_* functions

>>   nptl: Add C11 threads mtx_* functions

>>   nptl: Add C11 threads call_once functions

>>   nptl: Add C11 threads cnd_* functions

>>   nptl: Add C11 threads tss_* functions

>>   nptl: Add abilist symbols for C11 threads

>>   nptl: Add test cases for ISO C11 threads

>>

>> Juan Manuel Torres Palma (1):

>>   Add manual documentation for threads.h

>>

>>  ChangeLog                                          | 175 ++++++++++

>>  conform/Makefile                                   |   7 +-

>>  conform/data/threads.h-data                        |  57 ++++

>>  include/stdc-predef.h                              |   3 -

>>  manual/Makefile                                    |   2 +-

>>  manual/isothreads.texi                             | 355 +++++++++++++++++++++

>>  nptl/Makefile                                      |  15 +-

>>  nptl/Versions                                      |   9 +

>>  nptl/call_once.c                                   |  31 ++

>>  nptl/cnd_broadcast.c                               |  26 ++

>>  nptl/cnd_destroy.c                                 |  26 ++

>>  nptl/cnd_init.c                                    |  32 ++

>>  nptl/cnd_signal.c                                  |  26 ++

>>  nptl/cnd_timedwait.c                               |  29 ++

>>  nptl/cnd_wait.c                                    |  27 ++

>>  nptl/descr.h                                       |   2 +

>>  nptl/mtx_destroy.c                                 |  26 ++

>>  nptl/mtx_init.c                                    |  52 +++

>>  nptl/mtx_lock.c                                    |  26 ++

>>  nptl/mtx_timedlock.c                               |  28 ++

>>  nptl/mtx_trylock.c                                 |  26 ++

>>  nptl/mtx_unlock.c                                  |  26 ++

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

>>  nptl/tss_create.c                                  |  28 ++

>>  nptl/tss_delete.c                                  |  25 ++

>>  nptl/tss_get.c                                     |  25 ++

>>  nptl/tss_set.c                                     |  26 ++

>>  nptl/tst-call-once.c                               |  66 ++++

>>  nptl/tst-cnd-basic.c                               |  68 ++++

>>  nptl/tst-cnd-broadcast.c                           |  83 +++++

>>  nptl/tst-cnd-timedwait.c                           |  70 ++++

>>  nptl/tst-mtx-basic.c                               |  73 +++++

>>  nptl/tst-mtx-recursive.c                           |  45 +++

>>  nptl/tst-mtx-timedlock.c                           |  98 ++++++

>>  nptl/tst-mtx-trylock.c                             |  90 ++++++

>>  nptl/tst-thrd-detach.c                             |  52 +++

>>  nptl/tst-thrd-sleep.c                              |  51 +++

>>  nptl/tst-tss-basic.c                               |  75 +++++

>>  sysdeps/nptl/threads.h                             | 200 ++++++++++++

>>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist |  26 ++

>>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist   |  26 ++

>>  sysdeps/unix/sysv/linux/arm/libpthread.abilist     |  26 ++

>>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist    |  26 ++

>>  sysdeps/unix/sysv/linux/i386/libpthread.abilist    |  26 ++

>>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |  26 ++

>>  .../sysv/linux/m68k/coldfire/libpthread.abilist    |  26 ++

>>  .../unix/sysv/linux/m68k/m680x0/libpthread.abilist |  26 ++

>>  .../unix/sysv/linux/microblaze/libpthread.abilist  |  26 ++

>>  .../unix/sysv/linux/mips/mips32/libpthread.abilist |  26 ++

>>  .../unix/sysv/linux/mips/mips64/libpthread.abilist |  26 ++

>>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist   |  26 ++

>>  .../linux/powerpc/powerpc32/libpthread.abilist     |  26 ++

>>  .../linux/powerpc/powerpc64/libpthread-le.abilist  |  26 ++

>>  .../linux/powerpc/powerpc64/libpthread.abilist     |  26 ++

>>  .../unix/sysv/linux/riscv/rv64/libpthread.abilist  |  26 ++

>>  .../sysv/linux/s390/s390-32/libpthread.abilist     |  26 ++

>>  .../sysv/linux/s390/s390-64/libpthread.abilist     |  26 ++

>>  sysdeps/unix/sysv/linux/sh/libpthread.abilist      |  26 ++

>>  .../sysv/linux/sparc/sparc32/libpthread.abilist    |  26 ++

>>  .../sysv/linux/sparc/sparc64/libpthread.abilist    |  26 ++

>>  .../sysv/linux/tile/tilegx32/libpthread.abilist    |  26 ++

>>  .../sysv/linux/tile/tilegx64/libpthread.abilist    |  26 ++

>>  .../unix/sysv/linux/x86_64/64/libpthread.abilist   |  26 ++

>>  .../unix/sysv/linux/x86_64/x32/libpthread.abilist  |  26 ++

>>  74 files changed, 3011 insertions(+), 12 deletions(-)

>>  create mode 100644 conform/data/threads.h-data

>>  create mode 100644 manual/isothreads.texi

>>  create mode 100644 nptl/call_once.c

>>  create mode 100644 nptl/cnd_broadcast.c

>>  create mode 100644 nptl/cnd_destroy.c

>>  create mode 100644 nptl/cnd_init.c

>>  create mode 100644 nptl/cnd_signal.c

>>  create mode 100644 nptl/cnd_timedwait.c

>>  create mode 100644 nptl/cnd_wait.c

>>  create mode 100644 nptl/mtx_destroy.c

>>  create mode 100644 nptl/mtx_init.c

>>  create mode 100644 nptl/mtx_lock.c

>>  create mode 100644 nptl/mtx_timedlock.c

>>  create mode 100644 nptl/mtx_trylock.c

>>  create mode 100644 nptl/mtx_unlock.c

>>  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 nptl/tss_create.c

>>  create mode 100644 nptl/tss_delete.c

>>  create mode 100644 nptl/tss_get.c

>>  create mode 100644 nptl/tss_set.c

>>  create mode 100644 nptl/tst-call-once.c

>>  create mode 100644 nptl/tst-cnd-basic.c

>>  create mode 100644 nptl/tst-cnd-broadcast.c

>>  create mode 100644 nptl/tst-cnd-timedwait.c

>>  create mode 100644 nptl/tst-mtx-basic.c

>>  create mode 100644 nptl/tst-mtx-recursive.c

>>  create mode 100644 nptl/tst-mtx-timedlock.c

>>  create mode 100644 nptl/tst-mtx-trylock.c

>>  create mode 100644 nptl/tst-thrd-detach.c

>>  create mode 100644 nptl/tst-thrd-sleep.c

>>  create mode 100644 nptl/tst-tss-basic.c

>>  create mode 100644 sysdeps/nptl/threads.h

>>
Carlos O'Donell July 19, 2018, 6:43 p.m. UTC | #3
On 07/19/2018 01:46 PM, Adhemerval Zanella wrote:
> Florian, 

> 

> First thanks for the thoroughly review for c11 threads so far. I think it

> has covered most the upcoming rough pieces.

> 

> Carlos, do you think we can squeeze this for 2.28? As you put private, I

> also don't think we will get a 'pristine' implementation with optimal

> object sizes without a refactor of internal nptl implementation.


Yes, I'd like to see Intel CET, C11 threads, and malloc hook removal land
in this release.

It seems to me like ISO C threads.h is ready, were there any more objections?

Have we double checked with Joseph?

-- 
Cheers,
Carlos.
Rical Jasan July 19, 2018, 7:12 p.m. UTC | #4
On 07/19/2018 11:43 AM, Carlos O'Donell wrote:
> On 07/19/2018 01:46 PM, Adhemerval Zanella wrote:

>> Carlos, do you think we can squeeze this for 2.28? As you put private, I

>> also don't think we will get a 'pristine' implementation with optimal

>> object sizes without a refactor of internal nptl implementation.

> 

> Yes, I'd like to see Intel CET, C11 threads, and malloc hook removal land

> in this release.

> 

> It seems to me like ISO C threads.h is ready, were there any more objections?


I would like to see the manual content folded into the chapter we
already have for threads (threads.texi).  I can take care of the
mechanical bits for doing that, either as a revision of v8 8/8 or as a
follow-up commit, whichever would be preferred.

Rical
Adhemerval Zanella Netto July 19, 2018, 7:58 p.m. UTC | #5
On 19/07/2018 16:12, Rical Jasan wrote:
> On 07/19/2018 11:43 AM, Carlos O'Donell wrote:

>> On 07/19/2018 01:46 PM, Adhemerval Zanella wrote:

>>> Carlos, do you think we can squeeze this for 2.28? As you put private, I

>>> also don't think we will get a 'pristine' implementation with optimal

>>> object sizes without a refactor of internal nptl implementation.

>>

>> Yes, I'd like to see Intel CET, C11 threads, and malloc hook removal land

>> in this release.

>>

>> It seems to me like ISO C threads.h is ready, were there any more objections?

> 

> I would like to see the manual content folded into the chapter we

> already have for threads (threads.texi).  I can take care of the

> mechanical bits for doing that, either as a revision of v8 8/8 or as a

> follow-up commit, whichever would be preferred.

> 

> Rical

> 


If you could send a patch based on my personal branch [1] and can merge
it.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/c11-threads
Joseph Myers July 19, 2018, 9:26 p.m. UTC | #6
On Thu, 19 Jul 2018, Carlos O'Donell wrote:

> Yes, I'd like to see Intel CET, C11 threads, and malloc hook removal land

> in this release.

> 

> It seems to me like ISO C threads.h is ready, were there any more objections?

> 

> Have we double checked with Joseph?


I have not reviewed the details of the patches, but do not object to 
inclusion in 2.28 if the patches can be reviewed and committed within the 
next day, given that they were proposed well in advance of the freeze and 
have already gone through a few reviews.

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella Netto July 20, 2018, 12:32 p.m. UTC | #7
On 19/07/2018 18:26, Joseph Myers wrote:
> On Thu, 19 Jul 2018, Carlos O'Donell wrote:

> 

>> Yes, I'd like to see Intel CET, C11 threads, and malloc hook removal land

>> in this release.

>>

>> It seems to me like ISO C threads.h is ready, were there any more objections?

>>

>> Have we double checked with Joseph?

> 

> I have not reviewed the details of the patches, but do not object to 

> inclusion in 2.28 if the patches can be reviewed and committed within the 

> next day, given that they were proposed well in advance of the freeze and 

> have already gone through a few reviews.

> 


I think the patchset is in good shape overall, the only missing part without
revision is '[PATCH v8 4/8] nptl: Add C11 threads cnd_* functions' but it
should be simple since it is just wrappers around internal nptl calls.

The only missing piece is Racal has asked to fold the manual contents
chapter in threads.text. I will sort this out today.
Rical Jasan July 20, 2018, 1:22 p.m. UTC | #8
On 07/20/2018 05:32 AM, Adhemerval Zanella wrote:
> The only missing piece is Racal has asked to fold the manual contents

> chapter in threads.text. I will sort this out today.


I'm fixing this up as we speak; will have something soon.

Rical
Rical Jasan July 20, 2018, 1:54 p.m. UTC | #9
Should we really be saying "ISO C11" threads everywhere?  Would it be
appropriate to just say "ISO C"?  (I'm thinking about future ISO CXX
standards also having specifications for threads.)

Rical
Carlos O'Donell July 20, 2018, 2:04 p.m. UTC | #10
On 07/20/2018 09:54 AM, Rical Jasan wrote:
> Should we really be saying "ISO C11" threads everywhere?  Would it be

> appropriate to just say "ISO C"?  (I'm thinking about future ISO CXX

> standards also having specifications for threads.)


I'd prefer ISO C threads for more formal discussions, with C threads,
as opposed to POSIX threads, for less formal.

-- 
Cheers,
Carlos.
Rical Jasan July 20, 2018, 3:02 p.m. UTC | #11
Regarding thrd_exit, the new documentation is saying:

If this function is called from a single thread process, the call to
this function is equivalent to @code{exit(0)}.  Returning from a
thread-start function is equivalent to calling @code{thrd_exit}.

The standard says:

The program shall terminate normally after the last thread has been
terminated. The behavior shall be as if the program called the exit
function with the status EXIT_SUCCESS at thread termination time.

I came up with:

If this function is called from a single-threaded process, the call is
equivalent to calling @code{exit} with @code{EXIT_SUCCESS}
(@pxref{Normal Termination}).  Also note that returning from a function
that started a thread is equivalent to calling @code{thrd_exit}.


but I don't feel like the first sentence of each of those quite lines
up.  I suppose "single-threaded" and "last thread" could be used
interchangeably, but I don't think it gives the same impression.  Also,
the standard doesn't mention the function case.  Seems like a good
point, but maybe I'm not reading "thread-start function" right.

Any suggestions?

Thanks,
Rical
Rical Jasan July 21, 2018, 12:26 a.m. UTC | #12
On 07/19/2018 12:58 PM, Adhemerval Zanella wrote:
> If you could send a patch based on my personal branch [1] and can merge

> it.


I've attached the refactored/rewritten version.  It isn't a very long
section, so shouldn't take long to review (IANAE, so somebody should).

Aside from the refactoring to make the Threads chapter generic, I
reviewed the grammar, converted all references to "ISO C11" to "ISO C",
added @standards to everything, made sure all the relevant functions
mentioned their return values, and added cross-references where I felt
they would be useful.  I also reviewed the output in PDF, Info, and HTML
form.

I didn't mean to take so long, but I had to build make due a minimum
version requirement before I could review the output, and it took a lot
longer than building a single package like that usually does...

I didn't bother with the ChangeLog since I wasn't sure how you wanted to
handle that, and it changes all the time anyway.

Thanks,
Rical
commit 52d5f975656c61903d6a2fbb47a9ea460dd8db28
Author: Rical Jasan <ricaljasan@pacific.net>
Date:   Fri Jul 20 17:04:02 2018 -0700

    manual: Add documentation for ISO C Threads.
    
    The POSIX Threads chapter is renamed to Threads, making POSIX Threads
    a section, and a new section is added on the topic of ISO C Threads.
    
            * manual/debug.texi: Update adjacent chapter name.
            * manual/probes.texi: Likewise.
            * manual/threads.texi (ISO C Threads): New section.
            (POSIX Threads): Convert to a section.

diff --git a/manual/debug.texi b/manual/debug.texi
index f4157e525e..712a42f75c 100644
--- a/manual/debug.texi
+++ b/manual/debug.texi
@@ -1,5 +1,5 @@
 @node Debugging Support
-@c @node Debugging Support, POSIX Threads, Cryptographic Functions, Top
+@c @node Debugging Support, Threads, Cryptographic Functions, Top
 @c %MENU% Functions to help debugging applications
 @chapter Debugging support
 
diff --git a/manual/probes.texi b/manual/probes.texi
index fa6e38f785..ab2a3102bb 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -1,5 +1,5 @@
 @node Internal Probes
-@c @node Internal Probes, Tunables, POSIX Threads, Top
+@c @node Internal Probes, Tunables, Threads, Top
 @c %MENU% Probes to monitor libc internal behavior
 @chapter Internal probes
 
diff --git a/manual/threads.texi b/manual/threads.texi
index 769d974d50..01217e1c85 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -1,10 +1,538 @@
+@node Threads
+@c @node Threads, Internal Probes, Debugging Support, Top
+@c %MENU% Functions, constants, and data types for working with threads
+@chapter Threads
+@cindex threads
+
+This chapter describes functions used for managing threads.
+@Theglibc{} provides two threading implementations: ISO C threads and
+POSIX threads.
+
+@menu
+* ISO C Threads::	Threads based on the ISO C specification.
+* POSIX Threads::	Threads based on the POSIX specification.
+@end menu
+
+
+@node ISO C Threads
+@section ISO C Threads
+@cindex ISO C threads
+@cindex C threads
+@pindex threads.h
+
+This section describes the @glibcadj{} ISO C threads implementation.
+To have a deeper understanding of this API, it is strongly recomended
+to read ISO/IEC 9899:2011, section 7.26, in which ISO C threads were
+originally specified.  All types and function prototypes are declared
+in the header file @file{threads.h}.
+
+@menu
+* ISO C Threads Return Values:: Symbolic constants that represent a
+				function's return value.
+* ISO C Thread Management::	Support for basic threading.
+* Call Once::			Single-call functions and macros.
+* ISO C Mutexes::		A low-level mechanism for mutual exclusion.
+* ISO C Condition Variables::	High-level objects for thread synchronization.
+* ISO C Thread-local Storage::	Functions to support thread-local storage.
+@end menu
+
+
+@node ISO C Threads Return Values
+@subsection Return Values
+
+The ISO C thread specification provides the following enumeration
+constants for return values from functions in the API:
+
+@vtable @code
+@item thrd_timedout
+@standards{C11, threads.h}
+A specified time was reached without acquiring the requested resource,
+usually a mutex or condition variable.
+
+@item thrd_success
+@standards{C11, threads.h}
+The requested operation succeeded.
+
+@item thrd_busy
+@standards{C11, threads.h}
+The requested operation failed because a requested resource is already
+in use.
+
+@item thrd_error
+@standards{C11, threads.h}
+The requested operation failed.
+
+@item thrd_nomem
+@standards{C11, threads.h}
+The requested operation failed because it was unable to allocate
+enough memory.
+@end vtable
+
+
+@node ISO C Thread Management
+@subsection Creation and Control
+@cindex thread creation
+@cindex thread control
+@cindex thread management
+
+@Theglibc{} implements a set of functions that allow the user to easily
+create and use threads.  Additional functionality is provided to control
+the behavior of threads.
+
+The following data types are defined for managing threads:
+
+@deftp {Data Type} thrd_t
+@standards{C11, threads.h}
+A unique object that identifies a thread unequivocally.
+@end deftp
+
+@deftp {Data Type} thrd_start_t
+@standards{C11, threads.h}
+This data type is an @code{int (*) (void *)} typedef that is passed to
+@code{thrd_create} when creating a new thread.  It should point to the
+first function that thread will run.
+@end deftp
+
+The following functions are used for working with threads:
+
+@deftypefun int thrd_create (thrd_t *@var{thr}, thrd_start_t @var{func}, void *@var{arg})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_create} creates a new thread that will execute the function
+@var{func}.  The object pointed to by @var{arg} will be used as the
+argument to @var{func}.  If successful, @var{thr} is set to the new
+thread identifier.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun thrd_t thrd_current (void)
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This function returns the identifier of the calling thread.
+@end deftypefun
+
+@deftypefun int thrd_equal (thrd_t @var{lhs}, thrd_t @var{rhs})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_equal} checks whether @var{lhs} and @var{rhs} refer to the
+same thread.  If @var{lhs} and @var{rhs} are different threads, this
+function returns @math{0}; otherwise, the return value is non-zero.
+@end deftypefun
+
+@deftypefun int thrd_sleep (const struct timespec *@var{time_point}, struct timespec *@var{remaining})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_sleep} blocks the execution of the current thread for at
+least until the elapsed time pointed to by @var{time_point} has been
+reached.  This function does not take an absolute time, but a duration
+that the thread is required to be blocked.  @xref{Time Basics}, and
+@ref{Elapsed Time}.
+
+The thread may wake early if a signal that is not ignored is received.
+In such a case, if @code{remaining} is not NULL, the remaining time
+duration is stored in the object pointed to by
+@var{remaining}.
+
+@code{thrd_sleep} returns @math{0} if it blocked for at least the
+amount of time in @code{time_point}, @math{-1} if it was interrupted
+by a signal, or a negative number on failure.
+@end deftypefun
+
+@deftypefun void thrd_yield (void)
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_yield} provides a hint to the implementation to reschedule
+the execution of the current thread, allowing other threads to run.
+@end deftypefun
+
+@deftypefun {_Noreturn void} thrd_exit (int @var{res})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_exit} terminates execution of the calling thread and sets
+its result code to @var{res}.
+
+If this function is called from a single-threaded process, the call is
+equivalent to calling @code{exit} with @code{EXIT_SUCCESS}
+(@pxref{Normal Termination}).  Also note that returning from a
+function that started a thread is equivalent to calling
+@code{thrd_exit}.
+@end deftypefun
+
+@deftypefun int thrd_detach (thrd_t @var{thr})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_detach} detaches the thread identified by @code{thr} from
+the current control thread.  The resources held by the detached thread
+will be freed automatically once the thread exits.  The parent thread
+will never be notified by any @var{thr} signal.
+
+Calling @code{thrd_detach} on a thread that was previously detached or
+joined by another thread results in undefined behavior.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int thrd_join (thrd_t @var{thr}, int *@var{res})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_join} blocks the current thread until the thread identified
+by @code{thr} finishes execution.  If @code{res} is not NULL, the
+result code of the thread is put into the location pointed to by
+@var{res}.  The termination of the thread @dfn{synchronizes-with} the
+completion of this function, meaning both threads have arrived at a
+common point in their execution.
+
+Calling @code{thrd_join} on a thread that was previously detached or
+joined by another thread results in undefined behavior.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+
+@node Call Once
+@subsection Call Once
+@cindex call once
+@cindex single-call functions
+
+In order to guarantee single access to a function, @theglibc{}
+implements a @dfn{call once function} to ensure a function is only
+called once in the presence of multiple, potentially calling threads.
+
+@deftp {Data Type} once_flag
+@standards{C11, threads.h}
+A complete object type capable of holding a flag used by @code{call_once}.
+@end deftp
+
+@defvr Macro ONCE_FLAG_INIT
+@standards{C11, threads.h}
+This value is used to initialize an object of type @code{once_flag}.
+@end defvr
+
+@deftypefun void call_once (once_flag *@var{flag}, void (*@var{func}) (void))
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{call_once} calls function @var{func} exactly once, even if
+invoked from several threads.  The completion of the function
+@var{func} synchronizes-with all previous or subsequent calls to
+@code{call_once} with the same @code{flag} variable.
+@end deftypefun
+
+
+@node ISO C Mutexes
+@subsection Mutexes
+@cindex mutex
+@cindex mutual exclusion
+
+To have better control of resources and how threads access them,
+@theglibc{} implements a @dfn{mutex} object, which can help avoid race
+conditions and other concurrency issues.  The term ``mutex'' refers to
+mutual exclusion.
+
+The fundamental data type for a mutex is the @code{mtx_t}:
+
+@deftp {Data Type} mtx_t
+@standards{C11, threads.h}
+The @code{mtx_t} data type uniquely identifies a mutex object.
+@end deftp
+
+The ISO C standard defines several types of mutexes.  They are
+represented by the following symbolic constants:
+
+@vtable @code
+@item mtx_plain
+@standards{C11, threads.h}
+A mutex that does not support timeout, or test and return.
+
+@item mtx_recursive
+@standards{C11, threads.h}
+A mutex that supports recursive locking, which means that the owner
+thread can lock it more than once without causing deadlock.
+
+@item mtx_timed
+@standards{C11, threads.h}
+A mutex that supports timeout.
+@end vtable
+
+The following functions are used for working with mutexes:
+
+@deftypefun int mtx_init (mtx_t *@var{mutex}, int @var{type})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_init} creates a new mutex object with type @var{type}.  The
+object pointed to by @var{mutex} is set to the identifier of the newly
+created mutex.
+
+The @code{type} argument may be either @code{mtx_plain} or
+@code{mtx_timed}, optionally combined with @code{mtx_recursive}.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_lock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_lock} blocks the current thread until the mutex pointed to
+by @var{mutex} is locked.  The behavior is undefined if the current
+thread has already locked the mutex and the mutex is not recursive.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_timedlock (mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_timedlock} blocks the current thread until the mutex pointed
+to by @var{mutex} is locked or until the calendar time pointed to by
+@var{time_point} has been reached.  Since this function takes an
+absolute time, if a duration is required, the calendar time must be
+calculated manually.  @xref{Time Basics}, and @ref{Calendar Time}.
+
+If the current thread has already locked the mutex and the mutex is
+not recursive, or if the mutex does not support timeout, the behavior
+of this function is undefined.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_trylock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_trylock} tries to lock the mutex pointed to by @var{mutex}
+without blocking.  It returns immediately if the mutex is already
+locked.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns @code{thrd_success} if the lock was obtained,
+@code{thrd_busy} if the mutex is already locked, and @code{thrd_error}
+on failure.
+@end deftypefun
+
+@deftypefun int mtx_unlock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_unlock} unlocks the mutex pointed to by @var{mutex}.  The
+behavior is undefined if the mutex is not locked by the calling
+thread.
+
+This function synchronizes-with subsequent @code{mtx_lock},
+@code{mtx_trylock}, and @code{mtx_timedlock} calls on the same mutex.
+All lock/unlock operations on any given mutex form a single total
+order (similar to the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun void mtx_destroy (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_destroy} destroys the mutex pointed to by @var{mutex}.  If
+there are any threads waiting on the mutex, the behavior is
+undefined.
+@end deftypefun
+
+
+@node ISO C Condition Variables
+@subsection Condition Variables
+@cindex condvar
+@cindex condition variables
+
+Mutexes are not the only synchronization mechanisms available.  For
+some more complex tasks, @theglibc{} also implements @dfn{condition
+variables}, which allow the programmer to think at a higher level when
+solving complex synchronization problems.  They are used to
+synchronize threads waiting on a certain condition to happen.
+
+The fundamental data type for condition variables is the @code{cnd_t}:
+
+@deftp {Data Type} cnd_t
+@standards{C11, threads.h}
+The @code{cnd_t} uniquely identifies a condition variable object.
+@end deftp
+
+The following functions are used for working with condition variables:
+
+@deftypefun int cnd_init (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_init} initializes a new condition variable, identified by
+@var{cond}.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_signal (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_signal} unblocks one thread that is currently waiting on the
+condition variable pointed to by @var{cond}.  If a thread is
+successfully unblocked, this function returns @code{thrd_success}.  If
+no threads are blocked, this function does nothing and returns
+@code{thrd_success}.  Otherwise, this function returns
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_broadcast (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_broadcast} unblocks all the threads that are currently
+waiting on the condition variable pointed to by @var{cond}.  This
+function returns @code{thrd_success} on success.  If no threads are
+blocked, this function does nothing and returns
+@code{thrd_success}. Otherwise, this function returns
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_wait (cnd_t *@var{cond}, mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{cnd_wait} atomically unlocks the mutex pointed to by @var{mutex}
+and blocks on the condition variable pointed to by @var{cond} until
+the thread is signalled by @code{cnd_signal} or @code{cnd_broadcast}.
+The mutex is locked again before the function returns.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_timedwait (cnd_t *restrict @var{cond}, mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{cnd_timedwait} atomically unlocks the mutex pointed to by
+@var{mutex} and blocks on the condition variable pointed to by
+@var{cond} until the thread is signalled by @code{cnd_signal} or
+@code{cnd_broadcast}, or until the calendar time pointed to by
+@var{time_point} has been reached.  The mutex is locked again before
+the function returns.
+
+As for @code{mtx_timedlock}, since this function takes an absolute
+time, if a duration is required, the calendar time must be calculated
+manually.  @xref{Time Basics}, and @ref{Calendar Time}.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun void cnd_destroy (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_destroy} destroys the condition variable pointed to by
+@var{cond}.  If there are threads waiting on @var{cond}, the behavior
+is undefined.
+@end deftypefun
+
+
+@node ISO C Thread-local Storage
+@subsection Thread-local Storage
+@cindex thread-local storage
+
+@Theglibc{} implements functions to provide @dfn{thread-local
+storage}, which means each thread can have their own variables that
+are not visible by other threads.
+
+Several data types and macros exist for working with thread-local
+storage:
+
+@deftp {Data Type} tss_t
+@standards{C11, threads.h}
+The @code{tss_t} data type identifies a thread-specific storage
+object.  Even if shared, every thread will have its own instance of
+the variable, with different values.
+@end deftp
+
+@deftp {Data Type} tss_dtor_t
+@standards{C11, threads.h}
+The @code{tss_dtor_t} is a function pointer of type @code{void (*)
+(void *)}, to be used as a thread-specific storage destructor.  The
+function will be called when the current thread calls @code{thrd_exit}
+(but never when calling @code{tss_delete} or @code{exit}).
+@end deftp
+
+@defvr Macro thread_local
+@standards{C11, threads.h}
+@code{thread_local} is used to mark a variable with thread storage
+duration, which means it is created when the thread starts and cleaned
+up when the thread ends.
+
+@emph{Note:} For C++, C++11 or later is required to get the
+@code{thread_local} keyword.
+@end defvr
+
+@defvr Macro TSS_DTOR_ITERATIONS
+@standards{C11, threads.h}
+@code{TSS_DTOR_ITERATIONS} is an integer constant expression
+representing the maximum number of times that destructors will be
+called when a thread terminates.
+@end defvr
+
+The following functions are used to manage thread-local storage:
+
+@deftypefun int tss_create (tss_t *@var{tss_key}, tss_dtor_t @var{destructor})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_create} creates a new thread-specific storage key and stores
+it in the object pointed to by @var{tss_key}.  Although the same key
+value may be used by different threads, the values bound to the key by
+@code{tss_set} are maintained on a per-thread basis and persist for
+the life of the calling thread.
+
+If @code{destructor} is not NULL, a destructor function will be set,
+and called when the thread finishes its execution by calling
+@code{thrd_exit}.
+
+This function returns @code{thrd_success} if @code{tss_key} is
+successfully set to a unique value for the thread; otherwise,
+@code{thrd_error} is returned and the value of @code{tss_key} is
+undefined.
+@end deftypefun
+
+@deftypefun int tss_set (tss_t @var{tss_key}, void *@var{val})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_set} sets the value of the thread-specific storage
+identified by @var{tss_key} for the current thread to @var{val}.
+Different threads may set different values to the same key.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun {void *} tss_get (tss_t @var{tss_key})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_get} returns the value identified by @var{tss_key} held in
+thread-specific storage for the current thread.  Different threads may
+get different values identified by the same key.  On failure,
+@code{tss_get} returns zero.
+@end deftypefun
+
+@deftypefun void tss_delete (tss_t @var{tss_key})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_delete} destroys the thread-specific storage identified by
+@var{tss_key}.
+@end deftypefun
+
+
 @node POSIX Threads
-@c @node POSIX Threads, Internal Probes, Cryptographic Functions, Top
-@chapter POSIX Threads
-@c %MENU% POSIX Threads
+@section POSIX Threads
 @cindex pthreads
 
-This chapter describes the @glibcadj{} POSIX Threads implementation.
+This section describes the @glibcadj{} POSIX Threads implementation.
 
 @menu
 * Thread-specific Data::          Support for creating and
@@ -14,7 +542,7 @@ This chapter describes the @glibcadj{} POSIX Threads implementation.
 @end menu
 
 @node Thread-specific Data
-@section Thread-specific Data
+@subsection Thread-specific Data
 
 The @glibcadj{} implements functions to allow users to create and manage
 data specific to a thread.  Such data may be destroyed at thread exit,
@@ -71,7 +599,7 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread.
 
 
 @node Non-POSIX Extensions
-@section Non-POSIX Extensions
+@subsection Non-POSIX Extensions
 
 In addition to implementing the POSIX API for threads, @theglibc{} provides
 additional functions and interfaces to provide functionality not specified in
@@ -83,7 +611,7 @@ the standard.
 @end menu
 
 @node Default Thread Attributes
-@subsection Setting Process-wide defaults for thread attributes
+@subsubsection Setting Process-wide defaults for thread attributes
 
 @Theglibc{} provides non-standard API functions to set and get the default
 attributes used in the creation of threads in a process.
Carlos O'Donell July 21, 2018, 2:11 a.m. UTC | #13
On 07/20/2018 08:26 PM, Rical Jasan wrote:
> On 07/19/2018 12:58 PM, Adhemerval Zanella wrote:

>> If you could send a patch based on my personal branch [1] and can merge

>> it.

> I've attached the refactored/rewritten version.  It isn't a very long

> section, so shouldn't take long to review (IANAE, so somebody should).

> 

> Aside from the refactoring to make the Threads chapter generic, I

> reviewed the grammar, converted all references to "ISO C11" to "ISO C",

> added @standards to everything, made sure all the relevant functions

> mentioned their return values, and added cross-references where I felt

> they would be useful.  I also reviewed the output in PDF, Info, and HTML

> form.

> 

> I didn't mean to take so long, but I had to build make due a minimum

> version requirement before I could review the output, and it took a lot

> longer than building a single package like that usually does...

> 

> I didn't bother with the ChangeLog since I wasn't sure how you wanted to

> handle that, and it changes all the time anyway.


Great work here! Thank you for this help Rical!

OK for 2.28 with the follwing changes:

- Two spelling fixes.
- Consider suggestion for removing "unequivocally"
- Use "owning thread"
- Consider suggestion to expand thread type |'ing.
- Tighten up TLS language.
- You "use" a keyword.
- Broaden explanation of TSS_DTOR_ITERATIONS

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


> commit 52d5f975656c61903d6a2fbb47a9ea460dd8db28

> Author: Rical Jasan <ricaljasan@pacific.net>

> Date:   Fri Jul 20 17:04:02 2018 -0700

> 

>     manual: Add documentation for ISO C Threads.

>     

>     The POSIX Threads chapter is renamed to Threads, making POSIX Threads

>     a section, and a new section is added on the topic of ISO C Threads.

>     

>             * manual/debug.texi: Update adjacent chapter name.

>             * manual/probes.texi: Likewise.

>             * manual/threads.texi (ISO C Threads): New section.

>             (POSIX Threads): Convert to a section.

> 

> diff --git a/manual/debug.texi b/manual/debug.texi

> index f4157e525e..712a42f75c 100644

> --- a/manual/debug.texi

> +++ b/manual/debug.texi

> @@ -1,5 +1,5 @@

>  @node Debugging Support

> -@c @node Debugging Support, POSIX Threads, Cryptographic Functions, Top

> +@c @node Debugging Support, Threads, Cryptographic Functions, Top


OK.

>  @c %MENU% Functions to help debugging applications

>  @chapter Debugging support

>  

> diff --git a/manual/probes.texi b/manual/probes.texi

> index fa6e38f785..ab2a3102bb 100644

> --- a/manual/probes.texi

> +++ b/manual/probes.texi

> @@ -1,5 +1,5 @@

>  @node Internal Probes

> -@c @node Internal Probes, Tunables, POSIX Threads, Top

> +@c @node Internal Probes, Tunables, Threads, Top


OK.

>  @c %MENU% Probes to monitor libc internal behavior

>  @chapter Internal probes

>  

> diff --git a/manual/threads.texi b/manual/threads.texi

> index 769d974d50..01217e1c85 100644

> --- a/manual/threads.texi

> +++ b/manual/threads.texi

> @@ -1,10 +1,538 @@

> +@node Threads

> +@c @node Threads, Internal Probes, Debugging Support, Top

> +@c %MENU% Functions, constants, and data types for working with threads


OK.

> +@chapter Threads

> +@cindex threads

> +

> +This chapter describes functions used for managing threads.

> +@Theglibc{} provides two threading implementations: ISO C threads and

> +POSIX threads.


OK.

> +

> +@menu

> +* ISO C Threads::	Threads based on the ISO C specification.

> +* POSIX Threads::	Threads based on the POSIX specification.


OK. Yay!

> +@end menu

> +

> +

> +@node ISO C Threads

> +@section ISO C Threads

> +@cindex ISO C threads

> +@cindex C threads

> +@pindex threads.h

> +

> +This section describes the @glibcadj{} ISO C threads implementation.

> +To have a deeper understanding of this API, it is strongly recomended


s/recomended/recommended/g

> +to read ISO/IEC 9899:2011, section 7.26, in which ISO C threads were

> +originally specified.  All types and function prototypes are declared

> +in the header file @file{threads.h}.

> +

> +@menu

> +* ISO C Threads Return Values:: Symbolic constants that represent a

> +				function's return value.

> +* ISO C Thread Management::	Support for basic threading.

> +* Call Once::			Single-call functions and macros.

> +* ISO C Mutexes::		A low-level mechanism for mutual exclusion.

> +* ISO C Condition Variables::	High-level objects for thread synchronization.

> +* ISO C Thread-local Storage::	Functions to support thread-local storage.

> +@end menu


OK.

> +

> +

> +@node ISO C Threads Return Values

> +@subsection Return Values

> +

> +The ISO C thread specification provides the following enumeration

> +constants for return values from functions in the API:

> +

> +@vtable @code

> +@item thrd_timedout

> +@standards{C11, threads.h}

> +A specified time was reached without acquiring the requested resource,

> +usually a mutex or condition variable.

> +

> +@item thrd_success

> +@standards{C11, threads.h}

> +The requested operation succeeded.

> +

> +@item thrd_busy

> +@standards{C11, threads.h}

> +The requested operation failed because a requested resource is already

> +in use.

> +

> +@item thrd_error

> +@standards{C11, threads.h}

> +The requested operation failed.

> +

> +@item thrd_nomem

> +@standards{C11, threads.h}

> +The requested operation failed because it was unable to allocate

> +enough memory.

> +@end vtable


OK.

> +

> +

> +@node ISO C Thread Management

> +@subsection Creation and Control

> +@cindex thread creation

> +@cindex thread control

> +@cindex thread management

> +

> +@Theglibc{} implements a set of functions that allow the user to easily

> +create and use threads.  Additional functionality is provided to control

> +the behavior of threads.

> +

> +The following data types are defined for managing threads:

> +

> +@deftp {Data Type} thrd_t

> +@standards{C11, threads.h}

> +A unique object that identifies a thread unequivocally.


Suggest:
A unique object that identifies one thread.

Do more with less.

> +@end deftp

> +

> +@deftp {Data Type} thrd_start_t

> +@standards{C11, threads.h}

> +This data type is an @code{int (*) (void *)} typedef that is passed to

> +@code{thrd_create} when creating a new thread.  It should point to the

> +first function that thread will run.

> +@end deftp

> +

> +The following functions are used for working with threads:

> +

> +@deftypefun int thrd_create (thrd_t *@var{thr}, thrd_start_t @var{func}, void *@var{arg})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_create} creates a new thread that will execute the function

> +@var{func}.  The object pointed to by @var{arg} will be used as the

> +argument to @var{func}.  If successful, @var{thr} is set to the new

> +thread identifier.


OK.

> +

> +This function may return @code{thrd_success}, @code{thrd_nomem}, or

> +@code{thrd_error}.


OK.

> +@end deftypefun

> +

> +@deftypefun thrd_t thrd_current (void)

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +This function returns the identifier of the calling thread.

> +@end deftypefun

> +

> +@deftypefun int thrd_equal (thrd_t @var{lhs}, thrd_t @var{rhs})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_equal} checks whether @var{lhs} and @var{rhs} refer to the

> +same thread.  If @var{lhs} and @var{rhs} are different threads, this

> +function returns @math{0}; otherwise, the return value is non-zero.

> +@end deftypefun


OK.

> +

> +@deftypefun int thrd_sleep (const struct timespec *@var{time_point}, struct timespec *@var{remaining})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_sleep} blocks the execution of the current thread for at

> +least until the elapsed time pointed to by @var{time_point} has been

> +reached.  This function does not take an absolute time, but a duration

> +that the thread is required to be blocked.  @xref{Time Basics}, and

> +@ref{Elapsed Time}.

> +


OK.

> +The thread may wake early if a signal that is not ignored is received.

> +In such a case, if @code{remaining} is not NULL, the remaining time

> +duration is stored in the object pointed to by

> +@var{remaining}.


OK.

> +

> +@code{thrd_sleep} returns @math{0} if it blocked for at least the

> +amount of time in @code{time_point}, @math{-1} if it was interrupted

> +by a signal, or a negative number on failure.

> +@end deftypefun


OK.

> +

> +@deftypefun void thrd_yield (void)

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_yield} provides a hint to the implementation to reschedule

> +the execution of the current thread, allowing other threads to run.

> +@end deftypefun


OK.

> +

> +@deftypefun {_Noreturn void} thrd_exit (int @var{res})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_exit} terminates execution of the calling thread and sets

> +its result code to @var{res}.

> +

> +If this function is called from a single-threaded process, the call is

> +equivalent to calling @code{exit} with @code{EXIT_SUCCESS}

> +(@pxref{Normal Termination}).  Also note that returning from a

> +function that started a thread is equivalent to calling

> +@code{thrd_exit}.


This is the text you worried about.

On the one hand the standard says "last thread," but what does that mean?
It implies a total ordering of exiting threads, when that might not be true,
but both texts appear to assume it. Therefore it's fine for a first kick at
the can to describe what is happening.

In essence you had a multi-threaded program, and the threads start exiting,
and eventually you are left with just one thread whose thrd_exit is equivalent
to exit. It's a fine cognitive model, but assumes the implementation imposes
that total exit ordering in order for there to be a "last" thread, rather than
all threads exiting simultaneously and all of them being the "last" thread.

This looks good to me.

> +@end deftypefun

> +

> +@deftypefun int thrd_detach (thrd_t @var{thr})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_detach} detaches the thread identified by @code{thr} from

> +the current control thread.  The resources held by the detached thread

> +will be freed automatically once the thread exits.  The parent thread

> +will never be notified by any @var{thr} signal.

> +

> +Calling @code{thrd_detach} on a thread that was previously detached or

> +joined by another thread results in undefined behavior.

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun int thrd_join (thrd_t @var{thr}, int *@var{res})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{thrd_join} blocks the current thread until the thread identified

> +by @code{thr} finishes execution.  If @code{res} is not NULL, the

> +result code of the thread is put into the location pointed to by

> +@var{res}.  The termination of the thread @dfn{synchronizes-with} the

> +completion of this function, meaning both threads have arrived at a

> +common point in their execution.

> +

> +Calling @code{thrd_join} on a thread that was previously detached or

> +joined by another thread results in undefined behavior.

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +

> +@node Call Once

> +@subsection Call Once

> +@cindex call once

> +@cindex single-call functions

> +

> +In order to guarantee single access to a function, @theglibc{}

> +implements a @dfn{call once function} to ensure a function is only

> +called once in the presence of multiple, potentially calling threads.

> +

> +@deftp {Data Type} once_flag

> +@standards{C11, threads.h}

> +A complete object type capable of holding a flag used by @code{call_once}.

> +@end deftp

> +

> +@defvr Macro ONCE_FLAG_INIT

> +@standards{C11, threads.h}

> +This value is used to initialize an object of type @code{once_flag}.

> +@end defvr

> +

> +@deftypefun void call_once (once_flag *@var{flag}, void (*@var{func}) (void))

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{call_once} calls function @var{func} exactly once, even if

> +invoked from several threads.  The completion of the function

> +@var{func} synchronizes-with all previous or subsequent calls to

> +@code{call_once} with the same @code{flag} variable.

> +@end deftypefun


OK.

> +

> +

> +@node ISO C Mutexes

> +@subsection Mutexes

> +@cindex mutex

> +@cindex mutual exclusion

> +

> +To have better control of resources and how threads access them,

> +@theglibc{} implements a @dfn{mutex} object, which can help avoid race

> +conditions and other concurrency issues.  The term ``mutex'' refers to


OK.

> +mutual exclusion.

> +


OK.

> +The fundamental data type for a mutex is the @code{mtx_t}:

> +

> +@deftp {Data Type} mtx_t

> +@standards{C11, threads.h}

> +The @code{mtx_t} data type uniquely identifies a mutex object.

> +@end deftp

> +

> +The ISO C standard defines several types of mutexes.  They are

> +represented by the following symbolic constants:

> +

> +@vtable @code

> +@item mtx_plain

> +@standards{C11, threads.h}

> +A mutex that does not support timeout, or test and return.

> +

> +@item mtx_recursive

> +@standards{C11, threads.h}

> +A mutex that supports recursive locking, which means that the owner

> +thread can lock it more than once without causing deadlock.


Traditional technical language is "owning thread"

s/owner thread/owning thread/g

> +

> +@item mtx_timed

> +@standards{C11, threads.h}

> +A mutex that supports timeout.

> +@end vtable

> +

> +The following functions are used for working with mutexes:

> +

> +@deftypefun int mtx_init (mtx_t *@var{mutex}, int @var{type})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{mtx_init} creates a new mutex object with type @var{type}.  The

> +object pointed to by @var{mutex} is set to the identifier of the newly

> +created mutex.

> +

> +The @code{type} argument may be either @code{mtx_plain} or

> +@code{mtx_timed}, optionally combined with @code{mtx_recursive}.


This should be expanded to ensure clarity.

Suggest:
~~~
The @code{type} argument may be either @code{mtx_plain},
@code{mtx_timed}, @code{mtx_plain | mtx_recursive}, or 
@code{mtx_timed | mtx_recursive}.
~~~

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun int mtx_lock (mtx_t *@var{mutex})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

> +@code{mtx_lock} blocks the current thread until the mutex pointed to

> +by @var{mutex} is locked.  The behavior is undefined if the current

> +thread has already locked the mutex and the mutex is not recursive.

> +

> +Prior calls to @code{mtx_unlock} on the same mutex synchronize-with

> +this operation (if this operation succeeds), and all lock/unlock

> +operations on any given mutex form a single total order (similar to

> +the modification order of an atomic).

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun int mtx_timedlock (mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

> +@code{mtx_timedlock} blocks the current thread until the mutex pointed

> +to by @var{mutex} is locked or until the calendar time pointed to by

> +@var{time_point} has been reached.  Since this function takes an

> +absolute time, if a duration is required, the calendar time must be

> +calculated manually.  @xref{Time Basics}, and @ref{Calendar Time}.


OK.

> +

> +If the current thread has already locked the mutex and the mutex is

> +not recursive, or if the mutex does not support timeout, the behavior

> +of this function is undefined.

> +

> +Prior calls to @code{mtx_unlock} on the same mutex synchronize-with

> +this operation (if this operation succeeds), and all lock/unlock

> +operations on any given mutex form a single total order (similar to

> +the modification order of an atomic).

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun


OK.

> +

> +@deftypefun int mtx_trylock (mtx_t *@var{mutex})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

> +@code{mtx_trylock} tries to lock the mutex pointed to by @var{mutex}

> +without blocking.  It returns immediately if the mutex is already

> +locked.

> +

> +Prior calls to @code{mtx_unlock} on the same mutex synchronize-with

> +this operation (if this operation succeeds), and all lock/unlock

> +operations on any given mutex form a single total order (similar to

> +the modification order of an atomic).

> +

> +This function returns @code{thrd_success} if the lock was obtained,

> +@code{thrd_busy} if the mutex is already locked, and @code{thrd_error}

> +on failure.

> +@end deftypefun

> +

> +@deftypefun int mtx_unlock (mtx_t *@var{mutex})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{mtx_unlock} unlocks the mutex pointed to by @var{mutex}.  The

> +behavior is undefined if the mutex is not locked by the calling

> +thread.


OK. What about unlocking a lock you already unlocked?

> +

> +This function synchronizes-with subsequent @code{mtx_lock},

> +@code{mtx_trylock}, and @code{mtx_timedlock} calls on the same mutex.

> +All lock/unlock operations on any given mutex form a single total

> +order (similar to the modification order of an atomic).

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun void mtx_destroy (mtx_t *@var{mutex})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{mtx_destroy} destroys the mutex pointed to by @var{mutex}.  If

> +there are any threads waiting on the mutex, the behavior is

> +undefined.


OK.

> +@end deftypefun

> +

> +

> +@node ISO C Condition Variables

> +@subsection Condition Variables

> +@cindex condvar

> +@cindex condition variables

> +

> +Mutexes are not the only synchronization mechanisms available.  For

> +some more complex tasks, @theglibc{} also implements @dfn{condition

> +variables}, which allow the programmer to think at a higher level when

> +solving complex synchronization problems.  They are used to

> +synchronize threads waiting on a certain condition to happen.


OK.
> +

> +The fundamental data type for condition variables is the @code{cnd_t}:

> +

> +@deftp {Data Type} cnd_t

> +@standards{C11, threads.h}

> +The @code{cnd_t} uniquely identifies a condition variable object.

> +@end deftp

> +

> +The following functions are used for working with condition variables:

> +

> +@deftypefun int cnd_init (cnd_t *@var{cond})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{cnd_init} initializes a new condition variable, identified by

> +@var{cond}.

> +

> +This function may return @code{thrd_success}, @code{thrd_nomem}, or

> +@code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun int cnd_signal (cnd_t *@var{cond})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{cnd_signal} unblocks one thread that is currently waiting on the

> +condition variable pointed to by @var{cond}.  If a thread is

> +successfully unblocked, this function returns @code{thrd_success}.  If

> +no threads are blocked, this function does nothing and returns

> +@code{thrd_success}.  Otherwise, this function returns

> +@code{thrd_error}.

> +@end deftypefun


OK.

> +

> +@deftypefun int cnd_broadcast (cnd_t *@var{cond})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{cnd_broadcast} unblocks all the threads that are currently

> +waiting on the condition variable pointed to by @var{cond}.  This

> +function returns @code{thrd_success} on success.  If no threads are

> +blocked, this function does nothing and returns

> +@code{thrd_success}. Otherwise, this function returns

> +@code{thrd_error}.

> +@end deftypefun


OK.

> +

> +@deftypefun int cnd_wait (cnd_t *@var{cond}, mtx_t *@var{mutex})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

> +@code{cnd_wait} atomically unlocks the mutex pointed to by @var{mutex}

> +and blocks on the condition variable pointed to by @var{cond} until

> +the thread is signalled by @code{cnd_signal} or @code{cnd_broadcast}.


s/signalled/signaled/g

> +The mutex is locked again before the function returns.

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun int cnd_timedwait (cnd_t *restrict @var{cond}, mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

> +@code{cnd_timedwait} atomically unlocks the mutex pointed to by

> +@var{mutex} and blocks on the condition variable pointed to by

> +@var{cond} until the thread is signalled by @code{cnd_signal} or


s/signalled/signaled/g

> +@code{cnd_broadcast}, or until the calendar time pointed to by

> +@var{time_point} has been reached.  The mutex is locked again before

> +the function returns.

> +

> +As for @code{mtx_timedlock}, since this function takes an absolute

> +time, if a duration is required, the calendar time must be calculated

> +manually.  @xref{Time Basics}, and @ref{Calendar Time}.

> +


OK.

> +This function may return @code{thrd_success}, @code{thrd_nomem}, or

> +@code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun void cnd_destroy (cnd_t *@var{cond})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{cnd_destroy} destroys the condition variable pointed to by

> +@var{cond}.  If there are threads waiting on @var{cond}, the behavior

> +is undefined.

> +@end deftypefun


OK.

> +

> +

> +@node ISO C Thread-local Storage

> +@subsection Thread-local Storage

> +@cindex thread-local storage

> +

> +@Theglibc{} implements functions to provide @dfn{thread-local

> +storage}, which means each thread can have their own variables that

> +are not visible by other threads.


I would tighten this up a bit like this, since it's less about
visibility and more about storage:
~~~
@Theglibc{} implements functions to provide @dfn{thread-local
storage}. Variables can be defined to have unique storage per-thread,
lifetimes that match the thread lifetime, and destructors that cleanup
the unique per-thread storage.
~~~

> +

> +Several data types and macros exist for working with thread-local

> +storage:

> +

> +@deftp {Data Type} tss_t

> +@standards{C11, threads.h}

> +The @code{tss_t} data type identifies a thread-specific storage

> +object.  Even if shared, every thread will have its own instance of

> +the variable, with different values.

> +@end deftp


OK.

> +

> +@deftp {Data Type} tss_dtor_t

> +@standards{C11, threads.h}

> +The @code{tss_dtor_t} is a function pointer of type @code{void (*)

> +(void *)}, to be used as a thread-specific storage destructor.  The

> +function will be called when the current thread calls @code{thrd_exit}

> +(but never when calling @code{tss_delete} or @code{exit}).

> +@end deftp


OK.

> +

> +@defvr Macro thread_local

> +@standards{C11, threads.h}

> +@code{thread_local} is used to mark a variable with thread storage

> +duration, which means it is created when the thread starts and cleaned

> +up when the thread ends.


OK.

> +

> +@emph{Note:} For C++, C++11 or later is required to get the


s/get/use/g

You "use" a keyword.

> +@code{thread_local} keyword.

> +@end defvr

> +

> +@defvr Macro TSS_DTOR_ITERATIONS

> +@standards{C11, threads.h}

> +@code{TSS_DTOR_ITERATIONS} is an integer constant expression

> +representing the maximum number of times that destructors will be

> +called when a thread terminates.


Suggest a broader explanation:

@code{TSS_DTOR_ITERATIONS} is an integer constant expression
representing the maximum number of iterations over all thread-local
destructors at the time of thread termination. This value provides
a bounded limit to the destruction of thread-local storage e.g.
consider a destructor that creates more thread-local storage.

> +@end defvr

> +

> +The following functions are used to manage thread-local storage:

> +

> +@deftypefun int tss_create (tss_t *@var{tss_key}, tss_dtor_t @var{destructor})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{tss_create} creates a new thread-specific storage key and stores

> +it in the object pointed to by @var{tss_key}.  Although the same key

> +value may be used by different threads, the values bound to the key by

> +@code{tss_set} are maintained on a per-thread basis and persist for

> +the life of the calling thread.

> +

> +If @code{destructor} is not NULL, a destructor function will be set,

> +and called when the thread finishes its execution by calling

> +@code{thrd_exit}.

> +

> +This function returns @code{thrd_success} if @code{tss_key} is

> +successfully set to a unique value for the thread; otherwise,

> +@code{thrd_error} is returned and the value of @code{tss_key} is

> +undefined.

> +@end deftypefun


OK.

> +

> +@deftypefun int tss_set (tss_t @var{tss_key}, void *@var{val})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{tss_set} sets the value of the thread-specific storage

> +identified by @var{tss_key} for the current thread to @var{val}.

> +Different threads may set different values to the same key.


OK.

> +

> +This function returns either @code{thrd_success} or @code{thrd_error}.

> +@end deftypefun

> +

> +@deftypefun {void *} tss_get (tss_t @var{tss_key})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{tss_get} returns the value identified by @var{tss_key} held in

> +thread-specific storage for the current thread.  Different threads may

> +get different values identified by the same key.  On failure,

> +@code{tss_get} returns zero.

> +@end deftypefun


OK.

> +

> +@deftypefun void tss_delete (tss_t @var{tss_key})

> +@standards{C11, threads.h}

> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

> +@code{tss_delete} destroys the thread-specific storage identified by

> +@var{tss_key}.

> +@end deftypefun


OK.

> +

> +

>  @node POSIX Threads

> -@c @node POSIX Threads, Internal Probes, Cryptographic Functions, Top

> -@chapter POSIX Threads

> -@c %MENU% POSIX Threads

> +@section POSIX Threads


OK.

>  @cindex pthreads

>  

> -This chapter describes the @glibcadj{} POSIX Threads implementation.

> +This section describes the @glibcadj{} POSIX Threads implementation.

>  

>  @menu

>  * Thread-specific Data::          Support for creating and

> @@ -14,7 +542,7 @@ This chapter describes the @glibcadj{} POSIX Threads implementation.

>  @end menu

>  

>  @node Thread-specific Data

> -@section Thread-specific Data

> +@subsection Thread-specific Data

>  

>  The @glibcadj{} implements functions to allow users to create and manage

>  data specific to a thread.  Such data may be destroyed at thread exit,

> @@ -71,7 +599,7 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread.

>  

>  

>  @node Non-POSIX Extensions

> -@section Non-POSIX Extensions

> +@subsection Non-POSIX Extensions

>  

>  In addition to implementing the POSIX API for threads, @theglibc{} provides

>  additional functions and interfaces to provide functionality not specified in

> @@ -83,7 +611,7 @@ the standard.

>  @end menu

>  

>  @node Default Thread Attributes

> -@subsection Setting Process-wide defaults for thread attributes

> +@subsubsection Setting Process-wide defaults for thread attributes

>  


OK.

>  @Theglibc{} provides non-standard API functions to set and get the default

>  attributes used in the creation of threads in a process.



-- 
Cheers,
Carlos.
Rical Jasan July 21, 2018, 6:22 a.m. UTC | #14
On 07/20/2018 07:11 PM, Carlos O'Donell wrote:
> On 07/20/2018 08:26 PM, Rical Jasan wrote:

...
>> +This section describes the @glibcadj{} ISO C threads implementation.

>> +To have a deeper understanding of this API, it is strongly recomended

> 

> s/recomended/recommended/g


Fixed.

>> +@deftp {Data Type} thrd_t

>> +@standards{C11, threads.h}

>> +A unique object that identifies a thread unequivocally.

> 

> Suggest:

> A unique object that identifies one thread.

> 

> Do more with less.


I call, and raise you to "a thread".

>> +@item mtx_recursive

>> +@standards{C11, threads.h}

>> +A mutex that supports recursive locking, which means that the owner

>> +thread can lock it more than once without causing deadlock.

> 

> Traditional technical language is "owning thread"

> 

> s/owner thread/owning thread/g


Fixed.

>> +@deftypefun int mtx_init (mtx_t *@var{mutex}, int @var{type})

>> +@standards{C11, threads.h}

>> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

>> +@code{mtx_init} creates a new mutex object with type @var{type}.  The

>> +object pointed to by @var{mutex} is set to the identifier of the newly

>> +created mutex.

>> +

>> +The @code{type} argument may be either @code{mtx_plain} or

>> +@code{mtx_timed}, optionally combined with @code{mtx_recursive}.

> 

> This should be expanded to ensure clarity.

> 

> Suggest:

> ~~~

> The @code{type} argument may be either @code{mtx_plain},

> @code{mtx_timed}, @code{mtx_plain | mtx_recursive}, or 

> @code{mtx_timed | mtx_recursive}.

> ~~~


I turned this into a table.

>> +@deftypefun int mtx_unlock (mtx_t *@var{mutex})

>> +@standards{C11, threads.h}

>> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

>> +@code{mtx_unlock} unlocks the mutex pointed to by @var{mutex}.  The

>> +behavior is undefined if the mutex is not locked by the calling

>> +thread.

> 

> OK. What about unlocking a lock you already unlocked?


I don't know.  The specification is quiet on that point, as well as the
text I was working with.  nptl/mtx_unlock.c in Adhemerval's branch calls
__pthread_mutex_unlock.  In nptl/pthread_mutex_unlock.c, going through
the various tests for the mutex type (most of which result in a call to
lll_unlock or some variant), there are three tests that are conditional
upon "! lll_islocked", and they all return EPERM.  I believe, however,
that is an implementation detail we wouldn't necessarily include in the
manual, so the best I could say here is that it's UB because the spec
doesn't say anything about it.  (I didn't in the new patch, but I can
add that in if you like.)

>> +@deftypefun int cnd_wait (cnd_t *@var{cond}, mtx_t *@var{mutex})

>> +@standards{C11, threads.h}

>> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

>> +@code{cnd_wait} atomically unlocks the mutex pointed to by @var{mutex}

>> +and blocks on the condition variable pointed to by @var{cond} until

>> +the thread is signalled by @code{cnd_signal} or @code{cnd_broadcast}.

> 

> s/signalled/signaled/g


Fixed.

>> +@deftypefun int cnd_timedwait (cnd_t *restrict @var{cond}, mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})

>> +@standards{C11, threads.h}

>> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

>> +@code{cnd_timedwait} atomically unlocks the mutex pointed to by

>> +@var{mutex} and blocks on the condition variable pointed to by

>> +@var{cond} until the thread is signalled by @code{cnd_signal} or

> 

> s/signalled/signaled/g


Fixed.

>> +@Theglibc{} implements functions to provide @dfn{thread-local

>> +storage}, which means each thread can have their own variables that

>> +are not visible by other threads.

> 

> I would tighten this up a bit like this, since it's less about

> visibility and more about storage:

> ~~~

> @Theglibc{} implements functions to provide @dfn{thread-local

> storage}. Variables can be defined to have unique storage per-thread,

> lifetimes that match the thread lifetime, and destructors that cleanup

> the unique per-thread storage.

> ~~~


Fixed.  I joined it into one sentence to bind the explanation a little
more tightly to the @dfn.

>> +@emph{Note:} For C++, C++11 or later is required to get the

> 

> s/get/use/g

> 

> You "use" a keyword.


Fixed.

>> +@defvr Macro TSS_DTOR_ITERATIONS

>> +@standards{C11, threads.h}

>> +@code{TSS_DTOR_ITERATIONS} is an integer constant expression

>> +representing the maximum number of times that destructors will be

>> +called when a thread terminates.

> 

> Suggest a broader explanation:

> 

> @code{TSS_DTOR_ITERATIONS} is an integer constant expression

> representing the maximum number of iterations over all thread-local

> destructors at the time of thread termination. This value provides

> a bounded limit to the destruction of thread-local storage e.g.

> consider a destructor that creates more thread-local storage.


Thanks.  I had largely left that one alone.

Updated patch attached.

Rical
diff --git a/manual/debug.texi b/manual/debug.texi
index f4157e525e..712a42f75c 100644
--- a/manual/debug.texi
+++ b/manual/debug.texi
@@ -1,5 +1,5 @@
 @node Debugging Support
-@c @node Debugging Support, POSIX Threads, Cryptographic Functions, Top
+@c @node Debugging Support, Threads, Cryptographic Functions, Top
 @c %MENU% Functions to help debugging applications
 @chapter Debugging support
 
diff --git a/manual/probes.texi b/manual/probes.texi
index fa6e38f785..ab2a3102bb 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -1,5 +1,5 @@
 @node Internal Probes
-@c @node Internal Probes, Tunables, POSIX Threads, Top
+@c @node Internal Probes, Tunables, Threads, Top
 @c %MENU% Probes to monitor libc internal behavior
 @chapter Internal probes
 
diff --git a/manual/threads.texi b/manual/threads.texi
index 769d974d50..87fda7d8e7 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -1,10 +1,555 @@
+@node Threads
+@c @node Threads, Internal Probes, Debugging Support, Top
+@c %MENU% Functions, constants, and data types for working with threads
+@chapter Threads
+@cindex threads
+
+This chapter describes functions used for managing threads.
+@Theglibc{} provides two threading implementations: ISO C threads and
+POSIX threads.
+
+@menu
+* ISO C Threads::	Threads based on the ISO C specification.
+* POSIX Threads::	Threads based on the POSIX specification.
+@end menu
+
+
+@node ISO C Threads
+@section ISO C Threads
+@cindex ISO C threads
+@cindex C threads
+@pindex threads.h
+
+This section describes the @glibcadj{} ISO C threads implementation.
+To have a deeper understanding of this API, it is strongly recommended
+to read ISO/IEC 9899:2011, section 7.26, in which ISO C threads were
+originally specified.  All types and function prototypes are declared
+in the header file @file{threads.h}.
+
+@menu
+* ISO C Threads Return Values:: Symbolic constants that represent a
+				function's return value.
+* ISO C Thread Management::	Support for basic threading.
+* Call Once::			Single-call functions and macros.
+* ISO C Mutexes::		A low-level mechanism for mutual exclusion.
+* ISO C Condition Variables::	High-level objects for thread synchronization.
+* ISO C Thread-local Storage::	Functions to support thread-local storage.
+@end menu
+
+
+@node ISO C Threads Return Values
+@subsection Return Values
+
+The ISO C thread specification provides the following enumeration
+constants for return values from functions in the API:
+
+@vtable @code
+@item thrd_timedout
+@standards{C11, threads.h}
+A specified time was reached without acquiring the requested resource,
+usually a mutex or condition variable.
+
+@item thrd_success
+@standards{C11, threads.h}
+The requested operation succeeded.
+
+@item thrd_busy
+@standards{C11, threads.h}
+The requested operation failed because a requested resource is already
+in use.
+
+@item thrd_error
+@standards{C11, threads.h}
+The requested operation failed.
+
+@item thrd_nomem
+@standards{C11, threads.h}
+The requested operation failed because it was unable to allocate
+enough memory.
+@end vtable
+
+
+@node ISO C Thread Management
+@subsection Creation and Control
+@cindex thread creation
+@cindex thread control
+@cindex thread management
+
+@Theglibc{} implements a set of functions that allow the user to easily
+create and use threads.  Additional functionality is provided to control
+the behavior of threads.
+
+The following data types are defined for managing threads:
+
+@deftp {Data Type} thrd_t
+@standards{C11, threads.h}
+A unique object that identifies a thread.
+@end deftp
+
+@deftp {Data Type} thrd_start_t
+@standards{C11, threads.h}
+This data type is an @code{int (*) (void *)} typedef that is passed to
+@code{thrd_create} when creating a new thread.  It should point to the
+first function that thread will run.
+@end deftp
+
+The following functions are used for working with threads:
+
+@deftypefun int thrd_create (thrd_t *@var{thr}, thrd_start_t @var{func}, void *@var{arg})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_create} creates a new thread that will execute the function
+@var{func}.  The object pointed to by @var{arg} will be used as the
+argument to @var{func}.  If successful, @var{thr} is set to the new
+thread identifier.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun thrd_t thrd_current (void)
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This function returns the identifier of the calling thread.
+@end deftypefun
+
+@deftypefun int thrd_equal (thrd_t @var{lhs}, thrd_t @var{rhs})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_equal} checks whether @var{lhs} and @var{rhs} refer to the
+same thread.  If @var{lhs} and @var{rhs} are different threads, this
+function returns @math{0}; otherwise, the return value is non-zero.
+@end deftypefun
+
+@deftypefun int thrd_sleep (const struct timespec *@var{time_point}, struct timespec *@var{remaining})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_sleep} blocks the execution of the current thread for at
+least until the elapsed time pointed to by @var{time_point} has been
+reached.  This function does not take an absolute time, but a duration
+that the thread is required to be blocked.  @xref{Time Basics}, and
+@ref{Elapsed Time}.
+
+The thread may wake early if a signal that is not ignored is received.
+In such a case, if @code{remaining} is not NULL, the remaining time
+duration is stored in the object pointed to by
+@var{remaining}.
+
+@code{thrd_sleep} returns @math{0} if it blocked for at least the
+amount of time in @code{time_point}, @math{-1} if it was interrupted
+by a signal, or a negative number on failure.
+@end deftypefun
+
+@deftypefun void thrd_yield (void)
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_yield} provides a hint to the implementation to reschedule
+the execution of the current thread, allowing other threads to run.
+@end deftypefun
+
+@deftypefun {_Noreturn void} thrd_exit (int @var{res})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_exit} terminates execution of the calling thread and sets
+its result code to @var{res}.
+
+If this function is called from a single-threaded process, the call is
+equivalent to calling @code{exit} with @code{EXIT_SUCCESS}
+(@pxref{Normal Termination}).  Also note that returning from a
+function that started a thread is equivalent to calling
+@code{thrd_exit}.
+@end deftypefun
+
+@deftypefun int thrd_detach (thrd_t @var{thr})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_detach} detaches the thread identified by @code{thr} from
+the current control thread.  The resources held by the detached thread
+will be freed automatically once the thread exits.  The parent thread
+will never be notified by any @var{thr} signal.
+
+Calling @code{thrd_detach} on a thread that was previously detached or
+joined by another thread results in undefined behavior.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int thrd_join (thrd_t @var{thr}, int *@var{res})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{thrd_join} blocks the current thread until the thread identified
+by @code{thr} finishes execution.  If @code{res} is not NULL, the
+result code of the thread is put into the location pointed to by
+@var{res}.  The termination of the thread @dfn{synchronizes-with} the
+completion of this function, meaning both threads have arrived at a
+common point in their execution.
+
+Calling @code{thrd_join} on a thread that was previously detached or
+joined by another thread results in undefined behavior.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+
+@node Call Once
+@subsection Call Once
+@cindex call once
+@cindex single-call functions
+
+In order to guarantee single access to a function, @theglibc{}
+implements a @dfn{call once function} to ensure a function is only
+called once in the presence of multiple, potentially calling threads.
+
+@deftp {Data Type} once_flag
+@standards{C11, threads.h}
+A complete object type capable of holding a flag used by @code{call_once}.
+@end deftp
+
+@defvr Macro ONCE_FLAG_INIT
+@standards{C11, threads.h}
+This value is used to initialize an object of type @code{once_flag}.
+@end defvr
+
+@deftypefun void call_once (once_flag *@var{flag}, void (*@var{func}) (void))
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{call_once} calls function @var{func} exactly once, even if
+invoked from several threads.  The completion of the function
+@var{func} synchronizes-with all previous or subsequent calls to
+@code{call_once} with the same @code{flag} variable.
+@end deftypefun
+
+
+@node ISO C Mutexes
+@subsection Mutexes
+@cindex mutex
+@cindex mutual exclusion
+
+To have better control of resources and how threads access them,
+@theglibc{} implements a @dfn{mutex} object, which can help avoid race
+conditions and other concurrency issues.  The term ``mutex'' refers to
+mutual exclusion.
+
+The fundamental data type for a mutex is the @code{mtx_t}:
+
+@deftp {Data Type} mtx_t
+@standards{C11, threads.h}
+The @code{mtx_t} data type uniquely identifies a mutex object.
+@end deftp
+
+The ISO C standard defines several types of mutexes.  They are
+represented by the following symbolic constants:
+
+@vtable @code
+@item mtx_plain
+@standards{C11, threads.h}
+A mutex that does not support timeout, or test and return.
+
+@item mtx_recursive
+@standards{C11, threads.h}
+A mutex that supports recursive locking, which means that the owning
+thread can lock it more than once without causing deadlock.
+
+@item mtx_timed
+@standards{C11, threads.h}
+A mutex that supports timeout.
+@end vtable
+
+The following functions are used for working with mutexes:
+
+@deftypefun int mtx_init (mtx_t *@var{mutex}, int @var{type})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_init} creates a new mutex object with type @var{type}.  The
+object pointed to by @var{mutex} is set to the identifier of the newly
+created mutex.
+
+Not all combinations of mutex types are valid for the @code{type}
+argument.  Valid uses of mutex types for the @code{type} argument are:
+
+@table @code
+@item mtx_plain
+A non-recursive mutex that does not support timeout.
+
+@item mtx_timed
+A non-recursive mutex that does support timeout.
+
+@item mtx_plain | mtx_recursive
+A recursive mutex that does not support timeout.
+
+@item mtx_timed | mtx_recursive
+A recursive mutex that does support timeout.
+@end table
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_lock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_lock} blocks the current thread until the mutex pointed to
+by @var{mutex} is locked.  The behavior is undefined if the current
+thread has already locked the mutex and the mutex is not recursive.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_timedlock (mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_timedlock} blocks the current thread until the mutex pointed
+to by @var{mutex} is locked or until the calendar time pointed to by
+@var{time_point} has been reached.  Since this function takes an
+absolute time, if a duration is required, the calendar time must be
+calculated manually.  @xref{Time Basics}, and @ref{Calendar Time}.
+
+If the current thread has already locked the mutex and the mutex is
+not recursive, or if the mutex does not support timeout, the behavior
+of this function is undefined.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int mtx_trylock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{mtx_trylock} tries to lock the mutex pointed to by @var{mutex}
+without blocking.  It returns immediately if the mutex is already
+locked.
+
+Prior calls to @code{mtx_unlock} on the same mutex synchronize-with
+this operation (if this operation succeeds), and all lock/unlock
+operations on any given mutex form a single total order (similar to
+the modification order of an atomic).
+
+This function returns @code{thrd_success} if the lock was obtained,
+@code{thrd_busy} if the mutex is already locked, and @code{thrd_error}
+on failure.
+@end deftypefun
+
+@deftypefun int mtx_unlock (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_unlock} unlocks the mutex pointed to by @var{mutex}.  The
+behavior is undefined if the mutex is not locked by the calling
+thread.
+
+This function synchronizes-with subsequent @code{mtx_lock},
+@code{mtx_trylock}, and @code{mtx_timedlock} calls on the same mutex.
+All lock/unlock operations on any given mutex form a single total
+order (similar to the modification order of an atomic).
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun void mtx_destroy (mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{mtx_destroy} destroys the mutex pointed to by @var{mutex}.  If
+there are any threads waiting on the mutex, the behavior is
+undefined.
+@end deftypefun
+
+
+@node ISO C Condition Variables
+@subsection Condition Variables
+@cindex condvar
+@cindex condition variables
+
+Mutexes are not the only synchronization mechanisms available.  For
+some more complex tasks, @theglibc{} also implements @dfn{condition
+variables}, which allow the programmer to think at a higher level when
+solving complex synchronization problems.  They are used to
+synchronize threads waiting on a certain condition to happen.
+
+The fundamental data type for condition variables is the @code{cnd_t}:
+
+@deftp {Data Type} cnd_t
+@standards{C11, threads.h}
+The @code{cnd_t} uniquely identifies a condition variable object.
+@end deftp
+
+The following functions are used for working with condition variables:
+
+@deftypefun int cnd_init (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_init} initializes a new condition variable, identified by
+@var{cond}.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_signal (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_signal} unblocks one thread that is currently waiting on the
+condition variable pointed to by @var{cond}.  If a thread is
+successfully unblocked, this function returns @code{thrd_success}.  If
+no threads are blocked, this function does nothing and returns
+@code{thrd_success}.  Otherwise, this function returns
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_broadcast (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_broadcast} unblocks all the threads that are currently
+waiting on the condition variable pointed to by @var{cond}.  This
+function returns @code{thrd_success} on success.  If no threads are
+blocked, this function does nothing and returns
+@code{thrd_success}. Otherwise, this function returns
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_wait (cnd_t *@var{cond}, mtx_t *@var{mutex})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{cnd_wait} atomically unlocks the mutex pointed to by @var{mutex}
+and blocks on the condition variable pointed to by @var{cond} until
+the thread is signaled by @code{cnd_signal} or @code{cnd_broadcast}.
+The mutex is locked again before the function returns.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun int cnd_timedwait (cnd_t *restrict @var{cond}, mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@code{cnd_timedwait} atomically unlocks the mutex pointed to by
+@var{mutex} and blocks on the condition variable pointed to by
+@var{cond} until the thread is signaled by @code{cnd_signal} or
+@code{cnd_broadcast}, or until the calendar time pointed to by
+@var{time_point} has been reached.  The mutex is locked again before
+the function returns.
+
+As for @code{mtx_timedlock}, since this function takes an absolute
+time, if a duration is required, the calendar time must be calculated
+manually.  @xref{Time Basics}, and @ref{Calendar Time}.
+
+This function may return @code{thrd_success}, @code{thrd_nomem}, or
+@code{thrd_error}.
+@end deftypefun
+
+@deftypefun void cnd_destroy (cnd_t *@var{cond})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{cnd_destroy} destroys the condition variable pointed to by
+@var{cond}.  If there are threads waiting on @var{cond}, the behavior
+is undefined.
+@end deftypefun
+
+
+@node ISO C Thread-local Storage
+@subsection Thread-local Storage
+@cindex thread-local storage
+
+@Theglibc{} implements functions to provide @dfn{thread-local
+storage}, a mechanism by which variables can be defined to have unique
+per-thread storage, lifetimes that match the thread lifetime, and
+destructors that cleanup the unique per-thread storage.
+
+Several data types and macros exist for working with thread-local
+storage:
+
+@deftp {Data Type} tss_t
+@standards{C11, threads.h}
+The @code{tss_t} data type identifies a thread-specific storage
+object.  Even if shared, every thread will have its own instance of
+the variable, with different values.
+@end deftp
+
+@deftp {Data Type} tss_dtor_t
+@standards{C11, threads.h}
+The @code{tss_dtor_t} is a function pointer of type @code{void (*)
+(void *)}, to be used as a thread-specific storage destructor.  The
+function will be called when the current thread calls @code{thrd_exit}
+(but never when calling @code{tss_delete} or @code{exit}).
+@end deftp
+
+@defvr Macro thread_local
+@standards{C11, threads.h}
+@code{thread_local} is used to mark a variable with thread storage
+duration, which means it is created when the thread starts and cleaned
+up when the thread ends.
+
+@emph{Note:} For C++, C++11 or later is required to use the
+@code{thread_local} keyword.
+@end defvr
+
+@defvr Macro TSS_DTOR_ITERATIONS
+@standards{C11, threads.h}
+@code{TSS_DTOR_ITERATIONS} is an integer constant expression
+representing the maximum number of iterations over all thread-local
+destructors at the time of thread termination.  This value provides a
+bounded limit to the destruction of thread-local storage; e.g.,
+consider a destructor that creates more thread-local storage.
+@end defvr
+
+The following functions are used to manage thread-local storage:
+
+@deftypefun int tss_create (tss_t *@var{tss_key}, tss_dtor_t @var{destructor})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_create} creates a new thread-specific storage key and stores
+it in the object pointed to by @var{tss_key}.  Although the same key
+value may be used by different threads, the values bound to the key by
+@code{tss_set} are maintained on a per-thread basis and persist for
+the life of the calling thread.
+
+If @code{destructor} is not NULL, a destructor function will be set,
+and called when the thread finishes its execution by calling
+@code{thrd_exit}.
+
+This function returns @code{thrd_success} if @code{tss_key} is
+successfully set to a unique value for the thread; otherwise,
+@code{thrd_error} is returned and the value of @code{tss_key} is
+undefined.
+@end deftypefun
+
+@deftypefun int tss_set (tss_t @var{tss_key}, void *@var{val})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_set} sets the value of the thread-specific storage
+identified by @var{tss_key} for the current thread to @var{val}.
+Different threads may set different values to the same key.
+
+This function returns either @code{thrd_success} or @code{thrd_error}.
+@end deftypefun
+
+@deftypefun {void *} tss_get (tss_t @var{tss_key})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_get} returns the value identified by @var{tss_key} held in
+thread-specific storage for the current thread.  Different threads may
+get different values identified by the same key.  On failure,
+@code{tss_get} returns zero.
+@end deftypefun
+
+@deftypefun void tss_delete (tss_t @var{tss_key})
+@standards{C11, threads.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+@code{tss_delete} destroys the thread-specific storage identified by
+@var{tss_key}.
+@end deftypefun
+
+
 @node POSIX Threads
-@c @node POSIX Threads, Internal Probes, Cryptographic Functions, Top
-@chapter POSIX Threads
-@c %MENU% POSIX Threads
+@section POSIX Threads
 @cindex pthreads
 
-This chapter describes the @glibcadj{} POSIX Threads implementation.
+This section describes the @glibcadj{} POSIX Threads implementation.
 
 @menu
 * Thread-specific Data::          Support for creating and
@@ -14,7 +559,7 @@ This chapter describes the @glibcadj{} POSIX Threads implementation.
 @end menu
 
 @node Thread-specific Data
-@section Thread-specific Data
+@subsection Thread-specific Data
 
 The @glibcadj{} implements functions to allow users to create and manage
 data specific to a thread.  Such data may be destroyed at thread exit,
@@ -71,7 +616,7 @@ Associate the thread-specific @var{value} with @var{key} in the calling thread.
 
 
 @node Non-POSIX Extensions
-@section Non-POSIX Extensions
+@subsection Non-POSIX Extensions
 
 In addition to implementing the POSIX API for threads, @theglibc{} provides
 additional functions and interfaces to provide functionality not specified in
@@ -83,7 +628,7 @@ the standard.
 @end menu
 
 @node Default Thread Attributes
-@subsection Setting Process-wide defaults for thread attributes
+@subsubsection Setting Process-wide defaults for thread attributes
 
 @Theglibc{} provides non-standard API functions to set and get the default
 attributes used in the creation of threads in a process.
Adhemerval Zanella Netto July 21, 2018, 1:40 p.m. UTC | #15
On 21/07/2018 03:22, Rical Jasan wrote:
> On 07/20/2018 07:11 PM, Carlos O'Donell wrote:

>> On 07/20/2018 08:26 PM, Rical Jasan wrote:

> ...

>>> +This section describes the @glibcadj{} ISO C threads implementation.

>>> +To have a deeper understanding of this API, it is strongly recomended

>>

>> s/recomended/recommended/g

> 

> Fixed.

> 

>>> +@deftp {Data Type} thrd_t

>>> +@standards{C11, threads.h}

>>> +A unique object that identifies a thread unequivocally.

>>

>> Suggest:

>> A unique object that identifies one thread.

>>

>> Do more with less.

> 

> I call, and raise you to "a thread".

> 

>>> +@item mtx_recursive

>>> +@standards{C11, threads.h}

>>> +A mutex that supports recursive locking, which means that the owner

>>> +thread can lock it more than once without causing deadlock.

>>

>> Traditional technical language is "owning thread"

>>

>> s/owner thread/owning thread/g

> 

> Fixed.

> 

>>> +@deftypefun int mtx_init (mtx_t *@var{mutex}, int @var{type})

>>> +@standards{C11, threads.h}

>>> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

>>> +@code{mtx_init} creates a new mutex object with type @var{type}.  The

>>> +object pointed to by @var{mutex} is set to the identifier of the newly

>>> +created mutex.

>>> +

>>> +The @code{type} argument may be either @code{mtx_plain} or

>>> +@code{mtx_timed}, optionally combined with @code{mtx_recursive}.

>>

>> This should be expanded to ensure clarity.

>>

>> Suggest:

>> ~~~

>> The @code{type} argument may be either @code{mtx_plain},

>> @code{mtx_timed}, @code{mtx_plain | mtx_recursive}, or 

>> @code{mtx_timed | mtx_recursive}.

>> ~~~

> 

> I turned this into a table.

> 

>>> +@deftypefun int mtx_unlock (mtx_t *@var{mutex})

>>> +@standards{C11, threads.h}

>>> +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

>>> +@code{mtx_unlock} unlocks the mutex pointed to by @var{mutex}.  The

>>> +behavior is undefined if the mutex is not locked by the calling

>>> +thread.

>>

>> OK. What about unlocking a lock you already unlocked?

> 

> I don't know.  The specification is quiet on that point, as well as the

> text I was working with.  nptl/mtx_unlock.c in Adhemerval's branch calls

> __pthread_mutex_unlock.  In nptl/pthread_mutex_unlock.c, going through

> the various tests for the mutex type (most of which result in a call to

> lll_unlock or some variant), there are three tests that are conditional

> upon "! lll_islocked", and they all return EPERM.  I believe, however,

> that is an implementation detail we wouldn't necessarily include in the

> manual, so the best I could say here is that it's UB because the spec

> doesn't say anything about it.  (I didn't in the new patch, but I can

> add that in if you like.)

> 

>>> +@deftypefun int cnd_wait (cnd_t *@var{cond}, mtx_t *@var{mutex})

>>> +@standards{C11, threads.h}

>>> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

>>> +@code{cnd_wait} atomically unlocks the mutex pointed to by @var{mutex}

>>> +and blocks on the condition variable pointed to by @var{cond} until

>>> +the thread is signalled by @code{cnd_signal} or @code{cnd_broadcast}.

>>

>> s/signalled/signaled/g

> 

> Fixed.

> 

>>> +@deftypefun int cnd_timedwait (cnd_t *restrict @var{cond}, mtx_t *restrict @var{mutex}, const struct timespec *restrict @var{time_point})

>>> +@standards{C11, threads.h}

>>> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}

>>> +@code{cnd_timedwait} atomically unlocks the mutex pointed to by

>>> +@var{mutex} and blocks on the condition variable pointed to by

>>> +@var{cond} until the thread is signalled by @code{cnd_signal} or

>>

>> s/signalled/signaled/g

> 

> Fixed.

> 

>>> +@Theglibc{} implements functions to provide @dfn{thread-local

>>> +storage}, which means each thread can have their own variables that

>>> +are not visible by other threads.

>>

>> I would tighten this up a bit like this, since it's less about

>> visibility and more about storage:

>> ~~~

>> @Theglibc{} implements functions to provide @dfn{thread-local

>> storage}. Variables can be defined to have unique storage per-thread,

>> lifetimes that match the thread lifetime, and destructors that cleanup

>> the unique per-thread storage.

>> ~~~

> 

> Fixed.  I joined it into one sentence to bind the explanation a little

> more tightly to the @dfn.

> 

>>> +@emph{Note:} For C++, C++11 or later is required to get the

>>

>> s/get/use/g

>>

>> You "use" a keyword.

> 

> Fixed.

> 

>>> +@defvr Macro TSS_DTOR_ITERATIONS

>>> +@standards{C11, threads.h}

>>> +@code{TSS_DTOR_ITERATIONS} is an integer constant expression

>>> +representing the maximum number of times that destructors will be

>>> +called when a thread terminates.

>>

>> Suggest a broader explanation:

>>

>> @code{TSS_DTOR_ITERATIONS} is an integer constant expression

>> representing the maximum number of iterations over all thread-local

>> destructors at the time of thread termination. This value provides

>> a bounded limit to the destruction of thread-local storage e.g.

>> consider a destructor that creates more thread-local storage.

> 

> Thanks.  I had largely left that one alone.

> 

> Updated patch attached.

> 

> Rical

> 


Thanks, I pushed it on my personal branch [1] with you as author.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/c11-threads