0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <sys/time.h>
0011 #include <stdio.h>
0012 #include <signal.h>
0013 #include <unistd.h>
0014 #include <time.h>
0015 #include <pthread.h>
0016
0017 #include "../kselftest.h"
0018
0019 #define DELAY 2
0020 #define USECS_PER_SEC 1000000
0021
0022 static volatile int done;
0023
0024
0025 static void user_loop(void)
0026 {
0027 while (!done);
0028 }
0029
0030
0031
0032
0033
0034 static void kernel_loop(void)
0035 {
0036 void *addr = sbrk(0);
0037 int err = 0;
0038
0039 while (!done && !err) {
0040 err = brk(addr + 4096);
0041 err |= brk(addr);
0042 }
0043 }
0044
0045
0046
0047
0048 static void idle_loop(void)
0049 {
0050 pause();
0051 }
0052
0053 static void sig_handler(int nr)
0054 {
0055 done = 1;
0056 }
0057
0058
0059
0060
0061
0062 static int check_diff(struct timeval start, struct timeval end)
0063 {
0064 long long diff;
0065
0066 diff = end.tv_usec - start.tv_usec;
0067 diff += (end.tv_sec - start.tv_sec) * USECS_PER_SEC;
0068
0069 if (abs(diff - DELAY * USECS_PER_SEC) > USECS_PER_SEC / 2) {
0070 printf("Diff too high: %lld..", diff);
0071 return -1;
0072 }
0073
0074 return 0;
0075 }
0076
0077 static int check_itimer(int which)
0078 {
0079 int err;
0080 struct timeval start, end;
0081 struct itimerval val = {
0082 .it_value.tv_sec = DELAY,
0083 };
0084
0085 printf("Check itimer ");
0086
0087 if (which == ITIMER_VIRTUAL)
0088 printf("virtual... ");
0089 else if (which == ITIMER_PROF)
0090 printf("prof... ");
0091 else if (which == ITIMER_REAL)
0092 printf("real... ");
0093
0094 fflush(stdout);
0095
0096 done = 0;
0097
0098 if (which == ITIMER_VIRTUAL)
0099 signal(SIGVTALRM, sig_handler);
0100 else if (which == ITIMER_PROF)
0101 signal(SIGPROF, sig_handler);
0102 else if (which == ITIMER_REAL)
0103 signal(SIGALRM, sig_handler);
0104
0105 err = gettimeofday(&start, NULL);
0106 if (err < 0) {
0107 perror("Can't call gettimeofday()\n");
0108 return -1;
0109 }
0110
0111 err = setitimer(which, &val, NULL);
0112 if (err < 0) {
0113 perror("Can't set timer\n");
0114 return -1;
0115 }
0116
0117 if (which == ITIMER_VIRTUAL)
0118 user_loop();
0119 else if (which == ITIMER_PROF)
0120 kernel_loop();
0121 else if (which == ITIMER_REAL)
0122 idle_loop();
0123
0124 err = gettimeofday(&end, NULL);
0125 if (err < 0) {
0126 perror("Can't call gettimeofday()\n");
0127 return -1;
0128 }
0129
0130 if (!check_diff(start, end))
0131 printf("[OK]\n");
0132 else
0133 printf("[FAIL]\n");
0134
0135 return 0;
0136 }
0137
0138 static int check_timer_create(int which)
0139 {
0140 int err;
0141 timer_t id;
0142 struct timeval start, end;
0143 struct itimerspec val = {
0144 .it_value.tv_sec = DELAY,
0145 };
0146
0147 printf("Check timer_create() ");
0148 if (which == CLOCK_THREAD_CPUTIME_ID) {
0149 printf("per thread... ");
0150 } else if (which == CLOCK_PROCESS_CPUTIME_ID) {
0151 printf("per process... ");
0152 }
0153 fflush(stdout);
0154
0155 done = 0;
0156 err = timer_create(which, NULL, &id);
0157 if (err < 0) {
0158 perror("Can't create timer\n");
0159 return -1;
0160 }
0161 signal(SIGALRM, sig_handler);
0162
0163 err = gettimeofday(&start, NULL);
0164 if (err < 0) {
0165 perror("Can't call gettimeofday()\n");
0166 return -1;
0167 }
0168
0169 err = timer_settime(id, 0, &val, NULL);
0170 if (err < 0) {
0171 perror("Can't set timer\n");
0172 return -1;
0173 }
0174
0175 user_loop();
0176
0177 err = gettimeofday(&end, NULL);
0178 if (err < 0) {
0179 perror("Can't call gettimeofday()\n");
0180 return -1;
0181 }
0182
0183 if (!check_diff(start, end))
0184 printf("[OK]\n");
0185 else
0186 printf("[FAIL]\n");
0187
0188 return 0;
0189 }
0190
0191 int main(int argc, char **argv)
0192 {
0193 printf("Testing posix timers. False negative may happen on CPU execution \n");
0194 printf("based timers if other threads run on the CPU...\n");
0195
0196 if (check_itimer(ITIMER_VIRTUAL) < 0)
0197 return ksft_exit_fail();
0198
0199 if (check_itimer(ITIMER_PROF) < 0)
0200 return ksft_exit_fail();
0201
0202 if (check_itimer(ITIMER_REAL) < 0)
0203 return ksft_exit_fail();
0204
0205 if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
0206 return ksft_exit_fail();
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
0218 return ksft_exit_fail();
0219
0220 return ksft_exit_pass();
0221 }