1/* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * This file is licensed under the GPL license. For the full content 4 * of this license, see the COPYING file at the top level of this 5 * source tree. 6 * adam li 7 * 8 * Test that CLOCK_THREAD_CPUTIME_ID is supported by timer_create(). 9 * 10 * Same test as 1-1.c. 11 */ 12 13#include <time.h> 14#include <signal.h> 15#include <stdio.h> 16#include <unistd.h> 17#include <stdlib.h> 18#include "posixtest.h" 19 20#define SIGTOTEST SIGALRM 21#define TIMERSEC 2 22#define SLEEPDELTA 3 23#define ACCEPTABLEDELTA 1 24#define CLOCK_TO_TEST CLOCK_THREAD_CPUTIME_ID 25 26static int handlerInvoked = 0; 27 28static void sub_timespec(const struct timespec *a, const struct timespec *b, 29 struct timespec *result) 30{ 31 result->tv_sec = a->tv_sec - b->tv_sec; 32 result->tv_nsec = a->tv_nsec - b->tv_nsec; 33 if (result->tv_nsec < 0 && result->tv_sec > 0) { 34 result->tv_sec--; 35 result->tv_nsec += 1000000000; 36 } else if (result->tv_nsec >= 1000000000) { 37 result->tv_sec++; 38 result->tv_nsec -= 1000000000; 39 } 40} 41 42static int cmp_timespec(const struct timespec *a, const struct timespec *b) 43{ 44 if (a->tv_sec < b->tv_sec) 45 return -1; 46 if (a->tv_sec > b->tv_sec) 47 return 1; 48 49 if (a->tv_nsec < b->tv_nsec) 50 return -1; 51 if (a->tv_nsec > b->tv_nsec) 52 return 1; 53 54 return 0; 55} 56 57static int spin(const struct timespec *time, struct timespec *timeLeft) 58{ 59 struct timespec startTime; 60 61 if (clock_gettime(CLOCK_TO_TEST, &startTime) != 0) { 62 perror("clock_gettime() failed"); 63 exit(PTS_UNRESOLVED); 64 } 65 66 for (;;) { 67 struct timespec tempTime; 68 if (clock_gettime(CLOCK_TO_TEST, &tempTime) != 0) { 69 perror("clock_gettime() failed"); 70 exit(PTS_UNRESOLVED); 71 } 72 73 74 sub_timespec(&tempTime, &startTime, &tempTime); 75 if (cmp_timespec(time, &tempTime) <= 0) 76 return 0; 77 78 if (handlerInvoked) { 79 if (timeLeft) 80 sub_timespec(time, &tempTime, timeLeft); 81 return -1; 82 } 83 } 84} 85 86void handler(int signo) 87{ 88 printf("Caught signal\n"); 89 handlerInvoked = 1; 90} 91 92int main(int argc, char *argv[]) 93{ 94 int rc; 95 rc = sysconf(_SC_THREAD_CPUTIME); 96 printf("rc = %d\n", rc); 97 98#if _POSIX_THREAD_CPUTIME != -1 99 struct sigevent ev; 100 struct sigaction act; 101 timer_t tid; 102 struct itimerspec its; 103 struct timespec ts, tsleft; 104 105 if (rc == -1) { 106 printf("_POSIX_THREAD_CPUTIME unsupported\n"); 107 return PTS_UNSUPPORTED; 108 } 109 110 ev.sigev_notify = SIGEV_SIGNAL; 111 ev.sigev_signo = SIGTOTEST; 112 113 act.sa_handler=handler; 114 act.sa_flags=0; 115 116 its.it_interval.tv_sec = 0; 117 its.it_interval.tv_nsec = 0; 118 its.it_value.tv_sec = TIMERSEC; 119 its.it_value.tv_nsec = 0; 120 121 ts.tv_sec=TIMERSEC+SLEEPDELTA; 122 ts.tv_nsec=0; 123 124 if (sigemptyset(&act.sa_mask) == -1) { 125 perror("Error calling sigemptyset"); 126 return PTS_UNRESOLVED; 127 } 128 if (sigaction(SIGTOTEST, &act, 0) == -1) { 129 perror("Error calling sigaction"); 130 return PTS_UNRESOLVED; 131 } 132 133 if (timer_create(CLOCK_TO_TEST, &ev, &tid) != 0) { 134 perror("timer_create() did not return success"); 135 return PTS_UNRESOLVED; 136 } 137 138 if (timer_settime(tid, 0, &its, NULL) != 0) { 139 perror("timer_settime() did not return success"); 140 return PTS_UNRESOLVED; 141 } 142 143 if (spin(&ts, &tsleft) != -1) { 144 perror("nanosleep() not interrupted"); 145 return PTS_FAIL; 146 } 147 148 if ( abs(tsleft.tv_sec-SLEEPDELTA) <= ACCEPTABLEDELTA) { 149 printf("Test PASSED"); 150 return PTS_PASS; 151 } else { 152 printf("Timer did not last for correct amount of time\n"); 153 printf("timer: %d != correct %d\n", 154 (int) ts.tv_sec- (int) tsleft.tv_sec, 155 TIMERSEC); 156 return PTS_FAIL; 157 } 158 159 return PTS_UNRESOLVED; 160#else 161 printf("_POSIX_THREAD_CPUTIME unsupported\n"); 162 return PTS_UNSUPPORTED; 163#endif 164 165} 166