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_mutex_timedlock() 9 * locks the mutex object referenced by 'mutex'. If the mutex is 10 * already locked, the calling thread shall block until the mutex becomes 11 * available. The wait will end when the specified timeout time has expired. 12 13 * The timeout expires when the absolute time 'abs_timeout' passes, or if 'abs_timeout' 14 * has already been passed the time of the call. 15 16 * Steps: 17 * 18 * 1. Create a mutex in the main() thread and lock it. 19 * 2. Create a thread, and call pthread_mutex_timedlock inside of it. It should block for 20 * the set time of (3 secs.). 21 * 3. Save the time before and after the thread tried to lock the mutex. 22 * 4. After the thread has ended, main() will compare the times before and after the mutex 23 * tried to lock in the thread. 24 */ 25 26/* Test for CLOCK_REALTIME */ 27 28#define _XOPEN_SOURCE 600 29 30#include <time.h> 31#include <pthread.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <unistd.h> 35#include <errno.h> 36#include <sys/time.h> 37#include "posixtest.h" 38 39#define TIMEOUT 3 /* 3 seconds of timeout time for 40 pthread_mutex_timedlock(). */ 41void *f1(void *parm); 42 43pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* The mutex */ 44struct timeval currsec1, currsec2; /* Variables for saving time before 45 and after locking the mutex using 46 pthread_mutex_timedlock(). */ 47/**************************** 48 * 49 * MAIN() 50 * 51 * *************************/ 52int main(void) 53{ 54 pthread_t new_th; 55 struct timeval time_diff; 56 57 /* Lock the mutex. */ 58 if (pthread_mutex_lock(&mutex) != 0) { 59 perror("Error in pthread_mutex_lock().\n"); 60 return PTS_UNRESOLVED; 61 } 62 63 /* Create a thread that will call pthread_mutex_timedlock */ 64 if (pthread_create(&new_th, NULL, f1, NULL) != 0) { 65 perror("Error in pthread_create().\n"); 66 return PTS_UNRESOLVED; 67 } 68 69 /* Wait for thread to end. */ 70 if (pthread_join(new_th, NULL) != 0) { 71 perror("Error in pthread_join().\n"); 72 return PTS_UNRESOLVED; 73 } 74 75 /* Cleaning up the mutexes. */ 76 if (pthread_mutex_unlock(&mutex) != 0) { 77 perror("Error in pthread_mutex_unlock().\n"); 78 return PTS_UNRESOLVED; 79 } 80 if (pthread_mutex_destroy(&mutex) != 0) { 81 perror("Error in pthread_mutex_destroy().\n"); 82 return PTS_UNRESOLVED; 83 } 84 85 /* Compare time before the mutex locked and after the mutex lock timed out. */ 86 time_diff.tv_sec = currsec2.tv_sec - currsec1.tv_sec; 87 time_diff.tv_usec = currsec2.tv_usec - currsec1.tv_usec; 88 if (time_diff.tv_usec < 0) { 89 --time_diff.tv_sec; 90 time_diff.tv_usec += 1000000; 91 } 92 if (time_diff.tv_sec < TIMEOUT) { 93 printf 94 ("Test FAILED: Timed lock did not wait long enough. (%d secs.)\n", 95 TIMEOUT); 96 printf 97 ("time before mutex locked: %ld.%06ld, time after mutex timed out: %ld.%06ld.\n", 98 (long)currsec1.tv_sec, (long)currsec1.tv_usec, 99 (long)currsec2.tv_sec, (long)currsec2.tv_usec); 100 return PTS_FAIL; 101 } 102 103 printf("Test PASSED\n"); 104 return PTS_PASS; 105} 106 107/**************************** 108 * 109 * Thread's start routine. 110 * f1() 111 * 112 * *************************/ 113void *f1(void *parm) 114{ 115 struct timespec timeout, ts; 116 int rc; 117 /* Get the current time before the mutex locked. */ 118#ifdef CLOCK_REALTIME 119 printf("Test CLOCK_REALTIME\n"); 120 rc = clock_gettime(CLOCK_REALTIME, &ts); 121 if (rc != 0) { 122 perror("clock_gettime()"); 123 exit(PTS_UNRESOLVED); 124 } 125 currsec1.tv_sec = ts.tv_sec; 126 currsec1.tv_usec = ts.tv_nsec / 1000; 127#else 128 gettimeofday(&currsec1, NULL); 129#endif 130 /* Absolute time, not relative. */ 131 timeout.tv_sec = currsec1.tv_sec + TIMEOUT; 132 timeout.tv_nsec = currsec1.tv_usec * 1000; 133 134 printf 135 ("Timed mutex lock will block for %d seconds starting from: %ld.%06ld\n", 136 TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_usec); 137 if (pthread_mutex_timedlock(&mutex, &timeout) != ETIMEDOUT) { 138 perror("Error in pthread_mutex_timedlock().\n"); 139 pthread_exit((void *)PTS_UNRESOLVED); 140 return (void *)PTS_UNRESOLVED; 141 } 142 143 /* Get time after the mutex timed out in locking. */ 144#ifdef CLOCK_REALTIME 145 rc = clock_gettime(CLOCK_REALTIME, &ts); 146 if (rc != 0) { 147 perror("clock_gettime()"); 148 exit(PTS_UNRESOLVED); 149 } 150 currsec2.tv_sec = ts.tv_sec; 151 currsec2.tv_usec = ts.tv_nsec / 1000; 152#else 153 gettimeofday(&currsec2, NULL); 154#endif 155 pthread_exit(0); 156 return (void *)(0); 157} 158