1 /*
2 * Copyright (c) 2002, Intel Corporation. All rights reserved.
3 * Created by: bing.wei.liu REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license. For the full content
5 * of this license, see the COPYING file at the top level of this
6 * source tree.
7
8 * Test that pthread_cond_timedwait()
9 * shall be equivalent to pthread_cond_wait(), except that an error is returned
10 * if the absolute time specified by abstime passes before the condition cond is
11 * signaled or broadcasted, or if the absolute time specified by abstime has
12 * already been passed at the time of the call.
13 *
14 * Case 2-1
15 * Upon successful return, the mutex shall have been locked and shall
16 * be owned by the calling thread.
17 */
18
19
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <errno.h>
26 #include "posixtest.h"
27
28 #define INTERVAL 1
29 #define TIMEOUT 5
30
31 static struct testdata {
32 pthread_mutex_t mutex;
33 pthread_cond_t cond;
34 } td;
35
36 static int t1_start = 0;
37 static int signaled = 0;
38
t1_func(void * arg)39 static void *t1_func(void *arg)
40 {
41 int rc;
42 struct timespec timeout;
43 struct timeval curtime;
44
45 (void) arg;
46
47 if (pthread_mutex_lock(&td.mutex) != 0) {
48 fprintf(stderr, "Thread1 failed to acquire the mutex\n");
49 exit(PTS_UNRESOLVED);
50 }
51 fprintf(stderr, "Thread1 started\n");
52 t1_start = 1; /* let main thread continue */
53
54 if (gettimeofday(&curtime, NULL) != 0) {
55 fprintf(stderr, "Fail to get current time\n");
56 exit(PTS_UNRESOLVED);
57 }
58 timeout.tv_sec = curtime.tv_sec + TIMEOUT;
59 timeout.tv_nsec = curtime.tv_usec * 1000;
60
61 fprintf(stderr, "Thread1 is waiting for the cond\n");
62 rc = pthread_cond_timedwait(&td.cond, &td.mutex, &timeout);
63 if (rc != 0) {
64 if (rc == ETIMEDOUT) {
65 fprintf(stderr,
66 "Thread1 stops waiting when time is out\n");
67 exit(PTS_UNRESOLVED);
68 } else {
69 fprintf(stderr, "pthread_cond_timedwait return %d\n",
70 rc);
71 exit(PTS_UNRESOLVED);
72 }
73 }
74
75 fprintf(stderr, "Thread1 wakened\n");
76 if (signaled == 0) {
77 fprintf(stderr, "Thread1 did not block on the cond at all\n");
78 exit(PTS_UNRESOLVED);
79 }
80
81 if (pthread_mutex_trylock(&td.mutex) == 0) {
82 fprintf(stderr,
83 "Thread1 should not be able to lock the mutex again\n");
84 printf("Test FAILED\n");
85 exit(PTS_FAIL);
86 }
87 fprintf(stderr, "Thread1 failed to trylock the mutex (as expected)\n");
88
89 if (pthread_mutex_unlock(&td.mutex) != 0) {
90 fprintf(stderr, "Thread1 failed to release the mutex\n");
91 printf("Test FAILED\n");
92 exit(PTS_FAIL);
93 }
94 fprintf(stderr, "Thread1 released the mutex\n");
95 return NULL;
96 }
97
posix_testcase(void)98 static int posix_testcase(void)
99 {
100 pthread_t thread1;
101 struct timespec thread_start_ts = {0, 100000};
102
103 if (pthread_mutex_init(&td.mutex, NULL) != 0) {
104 fprintf(stderr, "Fail to initialize mutex\n");
105 return PTS_UNRESOLVED;
106 }
107 if (pthread_cond_init(&td.cond, NULL) != 0) {
108 fprintf(stderr, "Fail to initialize cond\n");
109 return PTS_UNRESOLVED;
110 }
111
112 if (pthread_create(&thread1, NULL, t1_func, NULL) != 0) {
113 fprintf(stderr, "Fail to create thread 1\n");
114 return PTS_UNRESOLVED;
115 }
116 while (!t1_start) /* wait for thread1 started */
117 nanosleep(&thread_start_ts, NULL);
118
119 /* acquire the mutex released by pthread_cond_wait() within thread 1 */
120 if (pthread_mutex_lock(&td.mutex) != 0) {
121 fprintf(stderr, "Main failed to acquire mutex\n");
122 return PTS_UNRESOLVED;
123 }
124 if (pthread_mutex_unlock(&td.mutex) != 0) {
125 fprintf(stderr, "Main failed to release mutex\n");
126 return PTS_UNRESOLVED;
127 }
128 sleep(INTERVAL);
129
130 fprintf(stderr, "Time to wake up thread1 by signaling a condition\n");
131 signaled = 1;
132 if (pthread_cond_signal(&td.cond) != 0) {
133 fprintf(stderr, "Main failed to signal the condition\n");
134 return PTS_UNRESOLVED;
135 }
136
137 pthread_join(thread1, NULL);
138 printf("Test PASSED\n");
139 return PTS_PASS;
140 }
141 #include <rtt_utest_internal.h>
142 UTEST_TC_EXPORT(testcase, "posix.pthread_cond_timedwait.2-1.c", RT_NULL, RT_NULL, 10);
143
144