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() 53{ 54 pthread_t new_th; 55 struct timeval time_diff; 56 57 /* Lock the mutex. */ 58 if(pthread_mutex_lock(&mutex) != 0) 59 { 60 perror("Error in pthread_mutex_lock().\n"); 61 return PTS_UNRESOLVED; 62 } 63 64 /* Create a thread that will call pthread_mutex_timedlock */ 65 if(pthread_create(&new_th, NULL, f1, NULL) != 0) 66 { 67 perror("Error in pthread_create().\n"); 68 return PTS_UNRESOLVED; 69 } 70 71 /* Wait for thread to end. */ 72 if(pthread_join(new_th, NULL) != 0) 73 { 74 perror("Error in pthread_join().\n"); 75 return PTS_UNRESOLVED; 76 } 77 78 /* Cleaning up the mutexes. */ 79 if(pthread_mutex_unlock(&mutex) != 0) 80 { 81 perror("Error in pthread_mutex_unlock().\n"); 82 return PTS_UNRESOLVED; 83 } 84 if(pthread_mutex_destroy(&mutex) != 0) 85 { 86 perror("Error in pthread_mutex_destroy().\n"); 87 return PTS_UNRESOLVED; 88 } 89 90 /* Compare time before the mutex locked and after the mutex lock timed out. */ 91 time_diff.tv_sec = currsec2.tv_sec - currsec1.tv_sec; 92 time_diff.tv_usec = currsec2.tv_usec - currsec1.tv_usec; 93 if (time_diff.tv_usec < 0) 94 { 95 --time_diff.tv_sec; 96 time_diff.tv_usec += 1000000; 97 } 98 if(time_diff.tv_sec < TIMEOUT) 99 { 100 printf("Test FAILED: Timed lock did not wait long enough. (%d secs.)\n", TIMEOUT); 101 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); 102 return PTS_FAIL; 103 } 104 105 printf("Test PASSED\n"); 106 return PTS_PASS; 107} 108 109/**************************** 110 * 111 * Thread's start routine. 112 * f1() 113 * 114 * *************************/ 115void *f1(void *parm) 116{ 117 struct timespec timeout, ts; 118 int rc; 119 /* Get the current time before the mutex locked. */ 120#ifdef CLOCK_REALTIME 121 printf("Test CLOCK_REALTIME\n"); 122 rc = clock_gettime(CLOCK_REALTIME, &ts); 123 if (rc != 0) 124 { 125 perror("clock_gettime()"); 126 exit(PTS_UNRESOLVED); 127 } 128 currsec1.tv_sec = ts.tv_sec; 129 currsec1.tv_usec = ts.tv_nsec / 1000; 130#else 131 (void)ts; 132 (void)rc; 133 gettimeofday(&currsec1, NULL); 134#endif 135 /* Absolute time, not relative. */ 136 timeout.tv_sec = currsec1.tv_sec + TIMEOUT; 137 timeout.tv_nsec = currsec1.tv_usec * 1000; 138 139 printf("Timed mutex lock will block for %d seconds starting from: %ld.%06ld\n", TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_usec); 140 if(pthread_mutex_timedlock(&mutex, &timeout) != ETIMEDOUT) 141 { 142 perror("Error in pthread_mutex_timedlock().\n"); 143 pthread_exit((void*)PTS_UNRESOLVED); 144 return (void*)PTS_UNRESOLVED; 145 } 146 147 /* Get time after the mutex timed out in locking. */ 148#ifdef CLOCK_REALTIME 149 rc = clock_gettime(CLOCK_REALTIME, &ts); 150 if (rc != 0) 151 { 152 perror("clock_gettime()"); 153 exit(PTS_UNRESOLVED); 154 } 155 currsec2.tv_sec = ts.tv_sec; 156 currsec2.tv_usec = ts.tv_nsec / 1000; 157#else 158 gettimeofday(&currsec2, NULL); 159#endif 160 pthread_exit(0); 161 return (void*)(0); 162} 163