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 block on a condition variable. It shall be called with mutex locked
10 *   by the calling thread or undefined behavior results.
11 */
12
13#define _XOPEN_SOURCE 600
14
15#include <pthread.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <unistd.h>
19#include <sys/time.h>
20#include <errno.h>
21#include "posixtest.h"
22
23#define TIMEOUT   5
24
25struct testdata
26{
27	pthread_mutex_t mutex;
28	pthread_cond_t  cond;
29} td;
30
31int t1_start = 0;
32int signaled = 0;
33
34void *t1_func(void *arg)
35{
36	int rc;
37	struct timespec timeout;
38	struct timeval  curtime;
39
40	if (pthread_mutex_lock(&td.mutex) != 0) {
41		fprintf(stderr,"Thread1: Fail to acquire mutex\n");
42		exit(PTS_UNRESOLVED);
43	}
44	fprintf(stderr,"Thread1 started\n");
45	t1_start = 1;	/* let main thread continue */
46
47	if (gettimeofday(&curtime, NULL) !=0 ) {
48		fprintf(stderr,"Fail to get current time\n");
49		exit(PTS_UNRESOLVED);
50	}
51	timeout.tv_sec = curtime.tv_sec;
52	timeout.tv_nsec = curtime.tv_usec * 1000;
53	timeout.tv_sec += TIMEOUT;
54
55	fprintf(stderr,"Thread1 is waiting for the cond\n");
56	rc = pthread_cond_timedwait(&td.cond, &td.mutex, &timeout);
57	if(rc != 0) {
58		if (rc == ETIMEDOUT) {
59			fprintf(stderr,"Thread1 stops waiting when time is out\n");
60			exit(PTS_UNRESOLVED);
61		}
62		else {
63			fprintf(stderr,"pthread_cond_timedwait return %d\n", rc);
64                	exit(PTS_UNRESOLVED);
65                }
66	}
67
68	fprintf(stderr,"Thread1 wakened up\n");
69	if(signaled == 0) {
70		fprintf(stderr,"Thread1 did not block on the cond at all\n");
71                printf("Test FAILED\n");
72                exit(PTS_FAIL);
73	}
74	pthread_mutex_unlock(&td.mutex);
75	return NULL;
76}
77
78int main()
79{
80	pthread_t  thread1;
81
82	if (pthread_mutex_init(&td.mutex, NULL) != 0) {
83		fprintf(stderr,"Fail to initialize mutex\n");
84		return PTS_UNRESOLVED;
85	}
86	if (pthread_cond_init(&td.cond, NULL) != 0) {
87		fprintf(stderr,"Fail to initialize cond\n");
88		return PTS_UNRESOLVED;
89	}
90
91	if (pthread_create(&thread1, NULL, t1_func, NULL) != 0) {
92		fprintf(stderr,"Fail to create thread 1\n");
93		return PTS_UNRESOLVED;
94	}
95	while(!t1_start)	/* wait for thread1 started */
96		usleep(100);
97
98	/* acquire the mutex released by pthread_cond_wait() within thread 1 */
99	if (pthread_mutex_lock(&td.mutex) != 0) {
100		fprintf(stderr,"Main: Fail to acquire mutex\n");
101		return PTS_UNRESOLVED;
102	}
103	if (pthread_mutex_unlock(&td.mutex) != 0) {
104		fprintf(stderr,"Main: Fail to release mutex\n");
105		return PTS_UNRESOLVED;
106	}
107	sleep(1);
108
109	fprintf(stderr,"Time to wake up thread1 by signaling a condition\n");
110	signaled = 1;
111	if (pthread_cond_signal(&td.cond) != 0) {
112		fprintf(stderr,"Main: Fail to signal cond\n");
113		return PTS_UNRESOLVED;
114	}
115
116	pthread_join(thread1, NULL);
117	printf("Test PASSED\n");
118	return PTS_PASS;
119}
120