]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 2003-2019 Free Software Foundation, Inc. |
61623643 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. | |
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 | |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
61623643 UD |
18 | |
19 | #include <errno.h> | |
20 | #include <pthread.h> | |
903ae060 | 21 | #include <stdint.h> |
61623643 | 22 | #include <stdio.h> |
903ae060 | 23 | #include <stdlib.h> |
61623643 UD |
24 | #include <string.h> |
25 | #include <unistd.h> | |
26 | #include <sys/mman.h> | |
903ae060 | 27 | #include <sys/time.h> |
61623643 | 28 | #include <sys/wait.h> |
ce5b73a7 MC |
29 | #include <support/check.h> |
30 | #include <support/timespec.h> | |
31 | #include <support/xunistd.h> | |
61623643 UD |
32 | |
33 | ||
9d20e22e MC |
34 | /* A bogus clock value that tells run_test to use pthread_mutex_timedlock |
35 | rather than pthread_mutex_clocklock. */ | |
36 | #define CLOCK_USE_TIMEDLOCK (-1) | |
37 | ||
38 | static void | |
39 | do_test_clock (clockid_t clockid) | |
61623643 | 40 | { |
9d20e22e MC |
41 | const clockid_t clockid_for_get = |
42 | (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid; | |
61623643 UD |
43 | size_t ps = sysconf (_SC_PAGESIZE); |
44 | char tmpfname[] = "/tmp/tst-mutex9.XXXXXX"; | |
45 | char data[ps]; | |
46 | void *mem; | |
47 | int fd; | |
48 | pthread_mutex_t *m; | |
49 | pthread_mutexattr_t a; | |
50 | pid_t pid; | |
61623643 UD |
51 | |
52 | fd = mkstemp (tmpfname); | |
53 | if (fd == -1) | |
ce5b73a7 | 54 | FAIL_EXIT1 ("cannot open temporary file: %m\n"); |
61623643 UD |
55 | |
56 | /* Make sure it is always removed. */ | |
57 | unlink (tmpfname); | |
58 | ||
59 | /* Create one page of data. */ | |
60 | memset (data, '\0', ps); | |
61 | ||
62 | /* Write the data to the file. */ | |
ce5b73a7 | 63 | xwrite (fd, data, ps); |
61623643 | 64 | |
ce5b73a7 | 65 | mem = xmmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd); |
61623643 UD |
66 | |
67 | m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t)) | |
68 | & ~(__alignof (pthread_mutex_t) - 1)); | |
61623643 | 69 | |
ce5b73a7 | 70 | TEST_COMPARE (pthread_mutexattr_init (&a), 0); |
61623643 | 71 | |
ce5b73a7 | 72 | TEST_COMPARE (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED), 0); |
61623643 | 73 | |
ce5b73a7 | 74 | TEST_COMPARE (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE), 0); |
61623643 | 75 | |
df47504c | 76 | #ifdef ENABLE_PI |
ce5b73a7 | 77 | TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0); |
df47504c UD |
78 | #endif |
79 | ||
80 | int e; | |
81 | if ((e = pthread_mutex_init (m, &a)) != 0) | |
82 | { | |
83 | #ifdef ENABLE_PI | |
84 | if (e == ENOTSUP) | |
ce5b73a7 | 85 | FAIL_UNSUPPORTED ("PI mutexes unsupported"); |
df47504c | 86 | #endif |
ce5b73a7 | 87 | FAIL_EXIT1 ("mutex_init failed"); |
61623643 UD |
88 | } |
89 | ||
ce5b73a7 | 90 | TEST_COMPARE (pthread_mutex_lock (m), 0); |
61623643 | 91 | |
ce5b73a7 | 92 | TEST_COMPARE (pthread_mutexattr_destroy (&a), 0); |
61623643 UD |
93 | |
94 | puts ("going to fork now"); | |
ce5b73a7 MC |
95 | pid = xfork (); |
96 | if (pid == 0) | |
61623643 UD |
97 | { |
98 | if (pthread_mutex_trylock (m) == 0) | |
ce5b73a7 | 99 | FAIL_EXIT1 ("child: mutex_trylock succeeded"); |
61623643 UD |
100 | |
101 | if (pthread_mutex_unlock (m) == 0) | |
ce5b73a7 MC |
102 | FAIL_EXIT1 ("child: mutex_unlock succeeded"); |
103 | ||
9d20e22e | 104 | const struct timespec ts = timespec_add (xclock_now (clockid_for_get), |
ce5b73a7 MC |
105 | make_timespec (0, 500000000)); |
106 | ||
9d20e22e MC |
107 | if (clockid == CLOCK_USE_TIMEDLOCK) |
108 | TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT); | |
109 | else | |
110 | TEST_COMPARE (pthread_mutex_clocklock (m, clockid, &ts), ETIMEDOUT); | |
61623643 UD |
111 | |
112 | alarm (1); | |
113 | ||
114 | pthread_mutex_lock (m); | |
115 | ||
116 | puts ("child: mutex_lock returned"); | |
117 | ||
118 | exit (0); | |
119 | } | |
120 | ||
121 | sleep (2); | |
122 | ||
123 | int status; | |
124 | if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) | |
ce5b73a7 | 125 | FAIL_EXIT1 ("waitpid failed"); |
61623643 | 126 | if (! WIFSIGNALED (status)) |
ce5b73a7 MC |
127 | FAIL_EXIT1 ("child not killed by signal"); |
128 | TEST_COMPARE (WTERMSIG (status), SIGALRM); | |
9d20e22e | 129 | } |
61623643 | 130 | |
9d20e22e MC |
131 | static int |
132 | do_test (void) | |
133 | { | |
134 | do_test_clock (CLOCK_USE_TIMEDLOCK); | |
135 | do_test_clock (CLOCK_REALTIME); | |
136 | do_test_clock (CLOCK_MONOTONIC); | |
61623643 | 137 | return 0; |
61623643 UD |
138 | } |
139 | ||
ce5b73a7 | 140 | #include <support/test-driver.c> |