Upload Tizen:Base source
[external/eglibc.git] / nptl / tst-mutex5.c
1 /* Copyright (C) 2002, 2003, 2004, 2006 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <time.h>
24 #include <unistd.h>
25 #include <sys/time.h>
26
27
28 #ifndef TYPE
29 # define TYPE PTHREAD_MUTEX_NORMAL
30 #endif
31
32
33 static int
34 do_test (void)
35 {
36   pthread_mutex_t m;
37   struct timespec ts;
38   struct timeval tv;
39   struct timeval tv2;
40   int err;
41   pthread_mutexattr_t a;
42
43   if (pthread_mutexattr_init (&a) != 0)
44     {
45       puts ("mutexattr_init failed");
46       return 1;
47     }
48
49   if (pthread_mutexattr_settype (&a, TYPE) != 0)
50     {
51       puts ("mutexattr_settype failed");
52       return 1;
53     }
54
55 #ifdef ENABLE_PI
56   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
57     {
58       puts ("pthread_mutexattr_setprotocol failed");
59       return 1;
60     }
61 #endif
62
63   err = pthread_mutex_init (&m, &a);
64   if (err != 0)
65     {
66 #ifdef ENABLE_PI
67       if (err == ENOTSUP)
68         {
69           puts ("PI mutexes unsupported");
70           return 0;
71         }
72 #endif
73       puts ("mutex_init failed");
74       return 1;
75     }
76
77   if (pthread_mutexattr_destroy (&a) != 0)
78     {
79       puts ("mutexattr_destroy failed");
80       return 1;
81     }
82
83   if (pthread_mutex_lock (&m) != 0)
84     {
85       puts ("mutex_lock failed");
86       return 1;
87     }
88
89   if (pthread_mutex_trylock (&m) == 0)
90     {
91       puts ("mutex_trylock succeeded");
92       return 1;
93     }
94
95   gettimeofday (&tv, NULL);
96   TIMEVAL_TO_TIMESPEC (&tv, &ts);
97
98   ts.tv_sec += 2;       /* Wait 2 seconds.  */
99
100   err = pthread_mutex_timedlock (&m, &ts);
101   if (err == 0)
102     {
103       puts ("timedlock succeeded");
104       return 1;
105     }
106   else if (err != ETIMEDOUT)
107     {
108       printf ("timedlock error != ETIMEDOUT: %d\n", err);
109       return 1;
110     }
111   else
112     {
113       int clk_tck = sysconf (_SC_CLK_TCK);
114
115       gettimeofday (&tv2, NULL);
116
117       tv2.tv_sec -= tv.tv_sec;
118       tv2.tv_usec -= tv.tv_usec;
119       if (tv2.tv_usec < 0)
120         {
121           tv2.tv_usec += 1000000;
122           tv2.tv_sec -= 1;
123         }
124
125       /* Be a bit tolerant, add one CLK_TCK.  */
126       tv2.tv_usec += 1000000 / clk_tck;
127       if (tv2.tv_usec >= 1000000)
128         {
129           tv2.tv_usec -= 1000000;
130           ++tv2.tv_sec;
131         }
132
133       if (tv2.tv_sec < 2)
134         {
135           printf ("premature timeout: %ld.%06ld difference\n",
136                   tv2.tv_sec, tv2.tv_usec);
137           return 1;
138         }
139     }
140
141   (void) gettimeofday (&tv, NULL);
142   TIMEVAL_TO_TIMESPEC (&tv, &ts);
143
144   ts.tv_sec += 2;       /* Wait 2 seconds.  */
145   /* The following makes the ts value invalid.  */
146   ts.tv_nsec += 1000000000;
147
148   err = pthread_mutex_timedlock (&m, &ts);
149   if (err == 0)
150     {
151       puts ("2nd timedlock succeeded");
152       return 1;
153     }
154   else if (err != EINVAL)
155     {
156       printf ("2nd timedlock error != EINVAL: %d\n", err);
157       return 1;
158     }
159
160   if (pthread_mutex_unlock (&m) != 0)
161     {
162       puts ("mutex_unlock failed");
163       return 1;
164     }
165
166   (void) gettimeofday (&tv, NULL);
167   TIMEVAL_TO_TIMESPEC (&tv, &ts);
168
169   ts.tv_sec += 2;       /* Wait 2 seconds.  */
170   if (pthread_mutex_timedlock (&m, &ts) != 0)
171     {
172       puts ("3rd timedlock failed");
173     }
174
175   (void) gettimeofday (&tv2, NULL);
176
177   /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
178   timersub (&tv2, &tv, &tv2);
179   if (tv2.tv_sec > 0 || tv2.tv_usec > 100000)
180     {
181       puts ("3rd timedlock didn't return right away");
182       return 1;
183     }
184
185   if (pthread_mutex_unlock (&m) != 0)
186     {
187       puts ("final mutex_unlock failed");
188       return 1;
189     }
190
191   if (pthread_mutex_destroy (&m) != 0)
192     {
193       puts ("mutex_destroy failed");
194       return 1;
195     }
196
197   return 0;
198 }
199
200 #define TIMEOUT 4
201 #define TEST_FUNCTION do_test ()
202 #include "../test-skeleton.c"