aboutsummaryrefslogtreecommitdiff
path: root/testcases/open_posix_testsuite/conformance/interfaces/pthread_mutex_timedlock/1-1.c
blob: 7527de13ad1e4de6a4f5fca51fcd41f9bd5624cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (c) 2002, Intel Corporation. All rights reserved.
 * Created by:  bing.wei.liu REMOVE-THIS AT intel DOT com
 * This file is licensed under the GPL license.  For the full content
 * of this license, see the COPYING file at the top level of this
 * source tree.

 * Test that pthread_mutex_timedlock()
 * locks the mutex object referenced by 'mutex'.  If the mutex is
 * already locked, the calling thread shall block until the mutex becomes
 * available.  The wait will end when the specified timeout time has expired.

 * The timeout expires when the absolute time 'abs_timeout' passes, or if 'abs_timeout'
 * has already been passed the time of the call.

 * Steps:
 *
 * 1. Create a mutex in the main() thread and lock it.
 * 2. Create a thread, and call pthread_mutex_timedlock inside of it.  It should block for
 *    the set time of (3 secs.).
 * 3. Save the time before and after the thread tried to lock the mutex.
 * 4. After the thread has ended, main() will compare the times before and after the mutex
 *    tried to lock in the thread.
 */


#include <time.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include "posixtest.h"

#define TIMEOUT 3		/* 3 seconds of timeout time for
				   pthread_mutex_timedlock(). */
void *f1(void *parm);

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;	/* The mutex */
struct timeval currsec1, currsec2;	/* Variables for saving time before
					   and after locking the mutex using
					   pthread_mutex_timedlock(). */
/****************************
 *
 * MAIN()
 *
 * *************************/
int main(void)
{
	pthread_t new_th;
	struct timeval time_diff;

	/* Lock the mutex. */
	if (pthread_mutex_lock(&mutex) != 0) {
		perror("Error in pthread_mutex_lock().\n");
		return PTS_UNRESOLVED;
	}

	/* Create a thread that will call pthread_mutex_timedlock */
	if (pthread_create(&new_th, NULL, f1, NULL) != 0) {
		perror("Error in pthread_create().\n");
		return PTS_UNRESOLVED;
	}

	/* Wait for thread to end. */
	if (pthread_join(new_th, NULL) != 0) {
		perror("Error in pthread_join().\n");
		return PTS_UNRESOLVED;
	}

	/* Cleaning up the mutexes. */
	if (pthread_mutex_unlock(&mutex) != 0) {
		perror("Error in pthread_mutex_unlock().\n");
		return PTS_UNRESOLVED;
	}
	if (pthread_mutex_destroy(&mutex) != 0) {
		perror("Error in pthread_mutex_destroy().\n");
		return PTS_UNRESOLVED;
	}

	/* Compare time before the mutex locked and after the mutex lock timed out. */
	time_diff.tv_sec = currsec2.tv_sec - currsec1.tv_sec;
	time_diff.tv_usec = currsec2.tv_usec - currsec1.tv_usec;
	if (time_diff.tv_usec < 0) {
		--time_diff.tv_sec;
		time_diff.tv_usec += 1000000;
	}
	if (time_diff.tv_sec < TIMEOUT) {
		printf
		    ("Test FAILED: Timed lock did not wait long enough. (%d secs.)\n",
		     TIMEOUT);
		printf
		    ("time before mutex locked: %ld.%06ld, time after mutex timed out: %ld.%06ld.\n",
		     (long)currsec1.tv_sec, (long)currsec1.tv_usec,
		     (long)currsec2.tv_sec, (long)currsec2.tv_usec);
		return PTS_FAIL;
	}

	printf("Test PASSED\n");
	return PTS_PASS;
}

/****************************
 *
 * Thread's start routine.
 * f1()
 *
 * *************************/
void *f1(void *parm)
{
	struct timespec timeout;

	/* Get the current time before the mutex locked. */
	gettimeofday(&currsec1, NULL);

	/* Absolute time, not relative. */
	timeout.tv_sec = currsec1.tv_sec + TIMEOUT;
	timeout.tv_nsec = currsec1.tv_usec * 1000;

	printf
	    ("Timed mutex lock will block for %d seconds starting from: %ld.%06ld\n",
	     TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_usec);
	if (pthread_mutex_timedlock(&mutex, &timeout) != ETIMEDOUT) {
		perror("Error in pthread_mutex_timedlock().\n");
		pthread_exit((void *)PTS_UNRESOLVED);
		return (void *)PTS_UNRESOLVED;
	}

	/* Get time after the mutex timed out in locking. */
	gettimeofday(&currsec2, NULL);

	pthread_exit(0);
	return (void *)(0);
}