1 /* Check if pthread_mutex_clocklock with PRIO_INHERIT fails with clock
2    different than CLOCK_REALTIME.
3    Copyright (C) 2020-2021 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5 
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10 
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15 
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <https://www.gnu.org/licenses/>.  */
19 
20 #include <pthread.h>
21 #include <errno.h>
22 #include <array_length.h>
23 
24 #include <support/check.h>
25 #include <support/xthread.h>
26 #include <support/timespec.h>
27 
28 static int
do_test(void)29 do_test (void)
30 {
31   const int types[] = {
32     PTHREAD_MUTEX_NORMAL,
33     PTHREAD_MUTEX_ERRORCHECK,
34     PTHREAD_MUTEX_RECURSIVE,
35     PTHREAD_MUTEX_ADAPTIVE_NP
36   };
37   const int robust[] = {
38     PTHREAD_MUTEX_STALLED,
39     PTHREAD_MUTEX_ROBUST
40   };
41   const struct {
42     int clk;
43     int r;
44   } clocks[] = {
45     { CLOCK_REALTIME,         0 },
46     { CLOCK_MONOTONIC,        0 },
47     { CLOCK_REALTIME_COARSE,  EINVAL }
48   };
49 
50   for (int t = 0; t < array_length (types); t++)
51     for (int r = 0; r < array_length (robust); r++)
52       for (int c = 0; c < array_length (clocks); c++)
53 	{
54 	  pthread_mutexattr_t attr;
55 	  xpthread_mutexattr_init (&attr);
56 	  xpthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT);
57 	  xpthread_mutexattr_settype (&attr, types[t]);
58 	  xpthread_mutexattr_setrobust (&attr, robust[r]);
59 
60 	  pthread_mutex_t mtx;
61 	  xpthread_mutex_init (&mtx, &attr);
62 
63 	  /* Uncontended case does not trigger any futex call.  */
64 	  struct timespec tmo = timespec_add (xclock_now (clocks[c].clk),
65 					      make_timespec (0, 100000000));
66 
67 	  TEST_COMPARE (pthread_mutex_clocklock (&mtx, clocks[c].clk, &tmo),
68 			clocks[c].r);
69 	  if (clocks[c].r == 0)
70 	    TEST_COMPARE (pthread_mutex_unlock (&mtx), 0);
71 
72 	  xpthread_mutex_destroy (&mtx);
73 	}
74 
75   return 0;
76 }
77 
78 #include <support/test-driver.c>
79