nptl: Add C11 threads mtx_* functions
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 27 Jun 2017 13:45:04 +0000 (10:45 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 24 Jul 2018 17:06:54 +0000 (14:06 -0300)
This patch adds the mtx_* definitions from C11 threads (ISO/IEC 9899:2011),
more specifically mtx_init, mtx_destroy, mtx_lock, mtx_timedlock, mtx_trylock,
mtx_unlock, and required types.

Mostly of the definitions are composed based on POSIX conterparts, and mtx_t
is also based on internal pthread fields, but with a distinct internal layout
to avoid possible issues with code interchange (such as trying to pass POSIX
structure on C11 functions and to avoid inclusion of pthread.h).  The idea
is to make possible to share POSIX internal implementations for mostly of
the code (and making adjustment only when required).

Checked with a build for all major ABI (aarch64-linux-gnu, alpha-linux-gnu,
arm-linux-gnueabi, i386-linux-gnu, ia64-linux-gnu, m68k-linux-gnu,
microblaze-linux-gnu [1], mips{64}-linux-gnu, nios2-linux-gnu,
powerpc{64le}-linux-gnu, s390{x}-linux-gnu, sparc{64}-linux-gnu,
and x86_64-linux-gnu).

Also ran a full check on aarch64-linux-gnu, x86_64-linux-gnu, i686-linux-gnu,
arm-linux-gnueabhf, and powerpc64le-linux-gnu.

[BZ #14092]
* conform/data/threads.h-data (mtx_plain): New constant.
(mtx_recursive): Likewise.
(mtx_timed): Likewise.
(mtx_t): New type.
(mtx_init): New function.
(mtx_lock): Likewise.
(mtx_timedlock): Likewise.
(mtx_trylock): Likewise.
(mtx_unlock): Likewise.
(mtx_destroy): Likewise.
* nptl/Makefile (libpthread-routines): Add mtx_destroy, mtx_init,
mtx_lock, mtx_timedlock, mtx_trylock, and mtx_unlock object.
* nptl/Versions (libpthread) [GLIBC_2.28]): Add mtx_init, mtx_lock,
mtx_timedlock, mtx_trylock, mtx_unlock, and mtx_destroy.
* nptl/mtx_destroy.c: New file.
* nptl/mtx_init.c: Likewise.
* nptl/mtx_lock.c: Likewise.
* nptl/mtx_timedlock.c: Likewise.
* nptl/mtx_trylock.c: Likewise.
* nptl/mtx_unlock.c: Likewise.
* sysdeps/nptl/threads.h (mtx_plain): New enumeration.
(mtx_recursive): Likewise.
(mtx_timed): Likewise.
(mtx_t): New type.
(mtx_init): New prototype.
(mtx_lock): Likewise.
(mtx_timedlock): Likewise.
(mtx_trylock): Likewise.
(mtx_unlock): Likewise.
(mtx_destroy): Likewise.

ChangeLog
conform/data/threads.h-data
nptl/Makefile
nptl/Versions
nptl/mtx_destroy.c [new file with mode: 0644]
nptl/mtx_init.c [new file with mode: 0644]
nptl/mtx_lock.c [new file with mode: 0644]
nptl/mtx_timedlock.c [new file with mode: 0644]
nptl/mtx_trylock.c [new file with mode: 0644]
nptl/mtx_unlock.c [new file with mode: 0644]
nptl/threads.h

index 5cafa4ccfde0087f9edb62820feac7f382b58ff5..1f04a0c64929f96f29d0bf41e3f653f1b4352ee1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,37 @@
 2018-07-24  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
+       [BZ #14092]
+       * conform/data/threads.h-data (mtx_plain): New constant.
+       (mtx_recursive): Likewise.
+       (mtx_timed): Likewise.
+       (mtx_t): New type.
+       (mtx_init): New function.
+       (mtx_lock): Likewise.
+       (mtx_timedlock): Likewise.
+       (mtx_trylock): Likewise.
+       (mtx_unlock): Likewise.
+       (mtx_destroy): Likewise.
+       * nptl/Makefile (libpthread-routines): Add mtx_destroy, mtx_init,
+       mtx_lock, mtx_timedlock, mtx_trylock, and mtx_unlock object.
+       * nptl/Versions (libpthread) [GLIBC_2.28]): Add mtx_init, mtx_lock,
+       mtx_timedlock, mtx_trylock, mtx_unlock, and mtx_destroy.
+       * nptl/mtx_destroy.c: New file.
+       * nptl/mtx_init.c: Likewise.
+       * nptl/mtx_lock.c: Likewise.
+       * nptl/mtx_timedlock.c: Likewise.
+       * nptl/mtx_trylock.c: Likewise.
+       * nptl/mtx_unlock.c: Likewise.
+       * sysdeps/nptl/threads.h (mtx_plain): New enumeration.
+       (mtx_recursive): Likewise.
+       (mtx_timed): Likewise.
+       (mtx_t): New type.
+       (mtx_init): New prototype.
+       (mtx_lock): Likewise.
+       (mtx_timedlock): Likewise.
+       (mtx_trylock): Likewise.
+       (mtx_unlock): Likewise.
+       (mtx_destroy): Likewise.
+
        [BZ #14092]
        * conform/Makefile (conformtest-headers-ISO11): Add threads.h.
        (linknamespace-libs-ISO11): Add libpthread.a.
index bc2d8578de6e5595749b64f11151fc15449985f7..bb5ca7552445fda1a8f7b3fa031a96b954e44755 100644 (file)
@@ -6,8 +6,13 @@ constant thrd_error
 constant thrd_nomem
 constant thrd_timedout
 
+constant mtx_plain
+constant mtx_recursive
+constant mtx_timed
+
 type thrd_t
 type thrd_start_t
+type mtx_t
 
 function int thrd_create (thrd_t*, thrd_start_t, void*)
 function int thrd_equal (thrd_t, thrd_t)
@@ -18,6 +23,13 @@ function int thrd_detach (thrd_t)
 function int thrd_join (thrd_t, int*)
 function void thrd_yield (void)
 
+function int mtx_init (mtx_t*, int)
+function int mtx_lock (mtx_t*)
+function int mtx_timedlock (mtx_t*, const struct timespec*)
+function int mtx_trylock (mtx_t*)
+function int mtx_unlock (mtx_t*)
+function void mtx_destroy (mtx_t*)
+
 #include "time.h-data"
 
 #endif
index 1fcf29f6c09c9903fe4503ded9e9f786a2282c66..4b889ab04e3a5264e214f1b4a5995665c895ca89 100644 (file)
@@ -141,7 +141,9 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
                      pthread_mutex_setprioceiling \
                      pthread_setname pthread_getname \
                      pthread_setattr_default_np pthread_getattr_default_np \
-                     thrd_create thrd_detach thrd_exit thrd_join
+                     thrd_create thrd_detach thrd_exit thrd_join \
+                     mtx_destroy mtx_init mtx_lock mtx_timedlock \
+                     mtx_trylock mtx_unlock
 #                    pthread_setuid pthread_seteuid pthread_setreuid \
 #                    pthread_setresuid \
 #                    pthread_setgid pthread_setegid pthread_setregid \
index 38d7e4804795a2e739172bdae1965ac8adac9af0..ca1be37354ddc5ea72c9f1e685b25a292de64a50 100644 (file)
@@ -272,6 +272,7 @@ libpthread {
   # C11 thread symbols.
   GLIBC_2.28 {
     thrd_create; thrd_detach; thrd_exit; thrd_join;
+    mtx_init; mtx_lock; mtx_timedlock; mtx_trylock; mtx_unlock; mtx_destroy;
   }
 
   GLIBC_PRIVATE {
diff --git a/nptl/mtx_destroy.c b/nptl/mtx_destroy.c
new file mode 100644 (file)
index 0000000..15bc022
--- /dev/null
@@ -0,0 +1,26 @@
+/* C11 threads mutex destroy implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+#include "pthreadP.h"
+
+void
+mtx_destroy (mtx_t *mutex)
+{
+  __pthread_mutex_destroy ((pthread_mutex_t *) mutex);
+}
diff --git a/nptl/mtx_init.c b/nptl/mtx_init.c
new file mode 100644 (file)
index 0000000..8f27478
--- /dev/null
@@ -0,0 +1,53 @@
+/* C11 threads mutex initialization implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdalign.h>
+
+#include "thrd_priv.h"
+
+int
+mtx_init (mtx_t *mutex, int type)
+{
+  _Static_assert (sizeof (mtx_t) == sizeof (pthread_mutex_t),
+                 "sizeof (mtx_t) != sizeof (pthread_mutex_t)");
+  _Static_assert (alignof (mtx_t) == alignof (pthread_mutex_t),
+                 "alignof (mtx_t) != alignof (pthread_mutex_t)");
+
+  pthread_mutexattr_t attr;
+
+  __pthread_mutexattr_init (&attr);
+
+  /* Another possible solution would be to set the flags directly in
+     mutex object. */
+  switch (type)
+  {
+    case mtx_plain | mtx_recursive:
+    case mtx_timed | mtx_recursive:
+      __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+      break;
+    case mtx_plain:
+    case mtx_timed: /* No difference between both in standard */
+    default:
+      __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_NORMAL);
+      break;
+  }
+
+  int err_code = __pthread_mutex_init ((pthread_mutex_t *) mutex, &attr);
+  /* pthread_mutexattr_destroy implementation is a noop.  */
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_lock.c b/nptl/mtx_lock.c
new file mode 100644 (file)
index 0000000..9b3e6cd
--- /dev/null
@@ -0,0 +1,26 @@
+/* C11 threads mutex lock implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+mtx_lock (mtx_t *mutex)
+{
+  int err_code = __pthread_mutex_lock ((pthread_mutex_t *) mutex);
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_timedlock.c b/nptl/mtx_timedlock.c
new file mode 100644 (file)
index 0000000..0972622
--- /dev/null
@@ -0,0 +1,28 @@
+/* C11 threads mutex timed lock implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+mtx_timedlock (mtx_t *restrict mutex,
+              const struct timespec *restrict time_point)
+{
+  int err_code = __pthread_mutex_timedlock ((pthread_mutex_t *)mutex,
+                                           time_point);
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_trylock.c b/nptl/mtx_trylock.c
new file mode 100644 (file)
index 0000000..f9b6a69
--- /dev/null
@@ -0,0 +1,26 @@
+/* C11 threads mutex try lock implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+mtx_trylock (mtx_t *mutex)
+{
+  int err_code = __pthread_mutex_trylock ((pthread_mutex_t *) mutex);
+  return thrd_err_map (err_code);
+}
diff --git a/nptl/mtx_unlock.c b/nptl/mtx_unlock.c
new file mode 100644 (file)
index 0000000..07f68f6
--- /dev/null
@@ -0,0 +1,26 @@
+/* C11 threads mutex unlock implementation.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thrd_priv.h"
+
+int
+mtx_unlock (mtx_t *mutex)
+{
+  int err_code = __pthread_mutex_unlock ((pthread_mutex_t *) mutex);
+  return thrd_err_map (err_code);
+}
index 5258e239198f1f6bfc69b1a105299a8ab51f4ba1..13d0075ea959c63092369e9c0dc9c36f22bbf0c1 100644 (file)
@@ -24,6 +24,7 @@
 
 __BEGIN_DECLS
 
+#include <bits/pthreadtypes-arch.h>
 #include <bits/types/struct_timespec.h>
 
 typedef unsigned long int thrd_t;
@@ -39,6 +40,20 @@ enum
   thrd_timedout = 4
 };
 
+/* Mutex types.  */
+enum
+{
+  mtx_plain     = 0,
+  mtx_recursive = 1,
+  mtx_timed     = 2
+};
+
+typedef union
+{
+  char __size[__SIZEOF_PTHREAD_MUTEX_T];
+  long int __align __LOCK_ALIGNMENT;
+} mtx_t;
+
 /* Threads functions.  */
 
 /* Create a new thread executing the function __FUNC.  Arguments for __FUNC
@@ -85,6 +100,35 @@ thrd_equal (thrd_t __thread1, thrd_t __thread2)
 }
 #endif
 
+
+/* Mutex functions.  */
+
+/* Creates a new mutex object with type __TYPE.  If successful the new
+   object is pointed by __MUTEX.  */
+extern int mtx_init (mtx_t *__mutex, int __type);
+
+/* Block the current thread until the mutex pointed to by __MUTEX is
+   unlocked.  In that case current thread will not be blocked.  */
+extern int mtx_lock (mtx_t *__mutex);
+
+/* Block the current thread until the mutex pointed by __MUTEX is unlocked
+   or time pointed by __TIME_POINT is reached.  In case the mutex is unlock,
+   the current thread will not be blocked.  */
+extern int mtx_timedlock (mtx_t *__restrict __mutex,
+                         const struct timespec *__restrict __time_point);
+
+/* Try to lock the mutex pointed by __MUTEX without blocking.  If the mutex
+   is free the current threads takes control of it, otherwise it returns
+   immediately.  */
+extern int mtx_trylock (mtx_t *__mutex);
+
+/* Unlock the mutex pointed by __MUTEX.  It may potentially awake other
+   threads waiting on this mutex.  */
+extern int mtx_unlock (mtx_t *__mutex);
+
+/* Destroy the mutex object pointed by __MUTEX.  */
+extern void mtx_destroy (mtx_t *__mutex);
+
 __END_DECLS
 
 #endif /* _THREADS_H */