fb27152ecc3a1c714cfcff0288de6850d208f5c4
[external/glibc.git] / nptl / tst-mutex5.c
1 /* Copyright (C) 2002-2019 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <errno.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <time.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <stdint.h>
26 #include <config.h>
27 #include <support/check.h>
28 #include <support/timespec.h>
29
30
31 #ifndef TYPE
32 # define TYPE PTHREAD_MUTEX_NORMAL
33 #endif
34
35
36 static int
37 do_test (void)
38 {
39   pthread_mutex_t m;
40   pthread_mutexattr_t a;
41
42   TEST_COMPARE (pthread_mutexattr_init (&a), 0);
43   TEST_COMPARE (pthread_mutexattr_settype (&a, TYPE), 0);
44
45 #ifdef ENABLE_PI
46   TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0);
47 #endif
48
49   int err = pthread_mutex_init (&m, &a);
50   if (err != 0)
51     {
52 #ifdef ENABLE_PI
53       if (err == ENOTSUP)
54         FAIL_UNSUPPORTED ("PI mutexes unsupported");
55 #endif
56       FAIL_EXIT1 ("mutex_init failed");
57     }
58
59   TEST_COMPARE (pthread_mutexattr_destroy (&a), 0);
60   TEST_COMPARE (pthread_mutex_lock (&m), 0);
61   if (pthread_mutex_trylock (&m) == 0)
62     FAIL_EXIT1 ("mutex_trylock succeeded");
63
64   /* Wait 2 seconds.  */
65   struct timespec ts_timeout = timespec_add (xclock_now (CLOCK_REALTIME),
66                                              make_timespec (2, 0));
67
68   TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
69   TEST_TIMESPEC_BEFORE_NOW (ts_timeout, CLOCK_REALTIME);
70
71   /* The following makes the ts value invalid.  */
72   ts_timeout.tv_nsec += 1000000000;
73
74   TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
75   TEST_COMPARE (pthread_mutex_unlock (&m), 0);
76
77   const struct timespec ts_start = xclock_now (CLOCK_REALTIME);
78
79   /* Wait 2 seconds.  */
80   ts_timeout = timespec_add (ts_start, make_timespec (2, 0));
81
82   TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
83
84   const struct timespec ts_end = xclock_now (CLOCK_REALTIME);
85
86   /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
87   TEST_TIMESPEC_BEFORE (ts_end,
88                         timespec_add (ts_start, make_timespec (0, 100000000)));
89
90   TEST_COMPARE (pthread_mutex_unlock (&m), 0);
91   TEST_COMPARE (pthread_mutex_destroy (&m), 0);
92
93   return 0;
94 }
95
96 #include <support/test-driver.c>