]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 2002-2019 Free Software Foundation, Inc. |
76a50749 UD |
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 | |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
76a50749 | 18 | |
df47504c | 19 | #include <errno.h> |
76a50749 UD |
20 | #include <pthread.h> |
21 | #include <stdio.h> | |
df47504c | 22 | #include <stdlib.h> |
76a50749 UD |
23 | #include <time.h> |
24 | ||
5920a4a6 CD |
25 | /* This test is a template for other tests to use. Other tests define |
26 | the following macros to change the behaviour of the template test. | |
27 | The test is very simple, it configures N threads given the parameters | |
28 | below and then proceeds to go through mutex lock and unlock | |
29 | operations in each thread as described before for the thread | |
30 | function. */ | |
df47504c UD |
31 | #ifndef TYPE |
32 | # define TYPE PTHREAD_MUTEX_DEFAULT | |
2c0b891a | 33 | #endif |
5920a4a6 CD |
34 | #ifndef ROBUST |
35 | # define ROBUST PTHREAD_MUTEX_STALLED | |
36 | #endif | |
37 | #ifndef DELAY_NSEC | |
38 | # define DELAY_NSEC 11000 | |
39 | #endif | |
40 | #ifndef ROUNDS | |
41 | # define ROUNDS 1000 | |
42 | #endif | |
43 | #ifndef N | |
44 | # define N 100 | |
45 | #endif | |
2c0b891a | 46 | |
df47504c | 47 | static pthread_mutex_t lock; |
76a50749 | 48 | |
5920a4a6 CD |
49 | /* Each thread locks and the subsequently unlocks the lock, yielding |
50 | the smallest critical section possible. After the unlock the thread | |
51 | waits DELAY_NSEC nanoseconds before doing the lock and unlock again. | |
52 | Every thread does this ROUNDS times. The lock and unlock are | |
53 | checked for errors. */ | |
76a50749 UD |
54 | static void * |
55 | tf (void *arg) | |
56 | { | |
57 | int nr = (long int) arg; | |
58 | int cnt; | |
5920a4a6 | 59 | struct timespec ts = { .tv_sec = 0, .tv_nsec = DELAY_NSEC }; |
76a50749 UD |
60 | |
61 | for (cnt = 0; cnt < ROUNDS; ++cnt) | |
62 | { | |
63 | if (pthread_mutex_lock (&lock) != 0) | |
64 | { | |
65 | printf ("thread %d: failed to get the lock\n", nr); | |
66 | return (void *) 1l; | |
67 | } | |
68 | ||
69 | if (pthread_mutex_unlock (&lock) != 0) | |
70 | { | |
71 | printf ("thread %d: failed to release the lock\n", nr); | |
72 | return (void *) 1l; | |
73 | } | |
74 | ||
5920a4a6 CD |
75 | if ((ts.tv_sec > 0) || (ts.tv_nsec > 0)) |
76 | nanosleep (&ts, NULL); | |
76a50749 UD |
77 | } |
78 | ||
79 | return NULL; | |
80 | } | |
81 | ||
5920a4a6 CD |
82 | /* Setup and run N threads, where each thread does as described |
83 | in the above thread function. The threads are given a minimal 1MiB | |
84 | stack since they don't do anything between the lock and unlock. */ | |
76a50749 UD |
85 | static int |
86 | do_test (void) | |
87 | { | |
df47504c UD |
88 | pthread_mutexattr_t a; |
89 | ||
90 | if (pthread_mutexattr_init (&a) != 0) | |
91 | { | |
92 | puts ("mutexattr_init failed"); | |
93 | exit (1); | |
94 | } | |
95 | ||
96 | if (pthread_mutexattr_settype (&a, TYPE) != 0) | |
97 | { | |
98 | puts ("mutexattr_settype failed"); | |
99 | exit (1); | |
100 | } | |
101 | ||
5920a4a6 CD |
102 | if (pthread_mutexattr_setrobust (&a, ROBUST) != 0) |
103 | { | |
104 | puts ("mutexattr_setrobust failed"); | |
105 | exit (1); | |
106 | } | |
107 | ||
df47504c UD |
108 | #ifdef ENABLE_PI |
109 | if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0) | |
110 | { | |
111 | puts ("pthread_mutexattr_setprotocol failed"); | |
112 | return 1; | |
113 | } | |
114 | #endif | |
115 | ||
116 | int e = pthread_mutex_init (&lock, &a); | |
117 | if (e != 0) | |
118 | { | |
119 | #ifdef ENABLE_PI | |
120 | if (e == ENOTSUP) | |
121 | { | |
122 | puts ("PI mutexes unsupported"); | |
123 | return 0; | |
124 | } | |
125 | #endif | |
126 | puts ("mutex_init failed"); | |
127 | return 1; | |
128 | } | |
129 | ||
130 | if (pthread_mutexattr_destroy (&a) != 0) | |
131 | { | |
132 | puts ("mutexattr_destroy failed"); | |
133 | return 1; | |
134 | } | |
135 | ||
4d1a02ef | 136 | pthread_attr_t at; |
76a50749 UD |
137 | pthread_t th[N]; |
138 | int cnt; | |
139 | ||
4d1a02ef UD |
140 | if (pthread_attr_init (&at) != 0) |
141 | { | |
142 | puts ("attr_init failed"); | |
143 | return 1; | |
144 | } | |
145 | ||
146 | if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0) | |
147 | { | |
148 | puts ("attr_setstacksize failed"); | |
149 | return 1; | |
150 | } | |
151 | ||
76a50749 UD |
152 | if (pthread_mutex_lock (&lock) != 0) |
153 | { | |
154 | puts ("locking in parent failed"); | |
155 | return 1; | |
156 | } | |
157 | ||
158 | for (cnt = 0; cnt < N; ++cnt) | |
4d1a02ef | 159 | if (pthread_create (&th[cnt], &at, tf, (void *) (long int) cnt) != 0) |
76a50749 UD |
160 | { |
161 | printf ("creating thread %d failed\n", cnt); | |
162 | return 1; | |
163 | } | |
164 | ||
4d1a02ef UD |
165 | if (pthread_attr_destroy (&at) != 0) |
166 | { | |
167 | puts ("attr_destroy failed"); | |
168 | return 1; | |
169 | } | |
170 | ||
76a50749 UD |
171 | if (pthread_mutex_unlock (&lock) != 0) |
172 | { | |
173 | puts ("unlocking in parent failed"); | |
174 | return 1; | |
175 | } | |
176 | ||
177 | for (cnt = 0; cnt < N; ++cnt) | |
178 | if (pthread_join (th[cnt], NULL) != 0) | |
179 | { | |
180 | printf ("joining thread %d failed\n", cnt); | |
181 | return 1; | |
182 | } | |
183 | ||
184 | return 0; | |
185 | } | |
186 | ||
187 | #define TIMEOUT 60 | |
188 | #define TEST_FUNCTION do_test () | |
189 | #include "../test-skeleton.c" |