PageRenderTime 25ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/minix/tests/test41.c

https://gitlab.com/storedmirrors/minix
C | 389 lines | 267 code | 100 blank | 22 comment | 136 complexity | d48dd64ae3c8c097ac7d65d850f3e480 MD5 | raw file
  1. /* Tests for getitimer(2)/setitimer(2) - by D.C. van Moolenbroek */
  2. /* Warning: this test deals with (real and virtual) time, and, lacking a proper
  3. * point of reference, its correctness depends on circumstances like CPU speed
  4. * and system load. A succeeding test run says a lot - failure not so much. */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <minix/config.h>
  10. #include <sys/types.h>
  11. #include <sys/time.h>
  12. #include <sys/wait.h>
  13. #include <sys/syslimits.h>
  14. #include <signal.h>
  15. #include <unistd.h>
  16. #include <errno.h>
  17. #define ITERATIONS 3
  18. int max_error = 4;
  19. #include "common.h"
  20. /* we have to keep in mind the millisecond values are rounded up */
  21. #define UPPERUSEC(us) ((us)+(1000000/system_hz))
  22. #define EQUSEC(l,r) \
  23. ((l) <= ((r) + (1000000/system_hz)) && (l) >= ((r) - (1000000/system_hz)))
  24. #define FILLITIMER(it, vs, vu, is, iu) \
  25. (it).it_value.tv_sec = (vs); \
  26. (it).it_value.tv_usec = (vu); \
  27. (it).it_interval.tv_sec = (is); \
  28. (it).it_interval.tv_usec = (iu);
  29. /* these two macros are not fully working for all possible values;
  30. * the tests only use values that the macros can deal with, though. */
  31. #define EQITIMER(it, vs, vu, is, iu) \
  32. ((it).it_value.tv_sec == (vs) && EQUSEC((it).it_value.tv_usec,vu) && \
  33. (it).it_interval.tv_sec == (is) && (it).it_interval.tv_usec == (iu))
  34. #define LEITIMER(it, vs, vu, is, iu) \
  35. ((it).it_value.tv_sec > 0 && ((it).it_value.tv_sec < (vs) || \
  36. ((it).it_value.tv_sec == (vs) && (it).it_value.tv_usec <= \
  37. UPPERUSEC(vu))) && \
  38. (it).it_interval.tv_sec == (is) && EQUSEC((it).it_interval.tv_usec,iu))
  39. int main(int argc, char **argv);
  40. void test(int m, int t);
  41. void test_which(void);
  42. void test_getset(void);
  43. void test_neglarge(void);
  44. void test_zero(void);
  45. void test_timer(void);
  46. void test_alarm(void);
  47. void test_fork(void);
  48. void test_exec(void);
  49. int do_check(void);
  50. void got_alarm(int sig);
  51. void busy_wait(int secs);
  52. #define my_e(n) do { printf("Timer %s, ", names[timer]); e(n); } while(0)
  53. static char *executable;
  54. static int signals;
  55. static int timer;
  56. static long system_hz;
  57. static int sigs[] = { SIGALRM, SIGVTALRM, SIGPROF };
  58. static const char *names[] = { "REAL", "VIRTUAL", "PROF" };
  59. int main(argc, argv)
  60. int argc;
  61. char **argv;
  62. {
  63. int i, m = 0xFFFF, n = 0xF;
  64. char cp_cmd[NAME_MAX+10];
  65. system_hz = sysconf(_SC_CLK_TCK);
  66. if (strcmp(argv[0], "DO CHECK") == 0) {
  67. timer = atoi(argv[1]);
  68. exit(do_check());
  69. }
  70. executable = argv[0];
  71. start(41);
  72. snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable);
  73. system(cp_cmd);
  74. if (argc >= 2) m = atoi(argv[1]);
  75. if (argc >= 3) n = atoi(argv[2]);
  76. for (i = 0; i < ITERATIONS; i++) {
  77. if (n & 1) test(m, ITIMER_REAL);
  78. if (n & 2) test(m, ITIMER_VIRTUAL);
  79. if (n & 4) test(m, ITIMER_PROF);
  80. }
  81. quit();
  82. return(-1); /* impossible */
  83. }
  84. void test(m, t)
  85. int m;
  86. int t;
  87. {
  88. timer = t;
  89. if (m & 0001) test_which();
  90. if (m & 0002) test_getset();
  91. if (m & 0004) test_neglarge();
  92. if (m & 0010) test_zero();
  93. if (m & 0020) test_timer();
  94. if (m & 0040) test_alarm();
  95. if (m & 0100) test_fork();
  96. if (m & 0200) test_exec();
  97. }
  98. /* test invalid and unsupported 'which' values */
  99. void test_which()
  100. {
  101. struct itimerval it;
  102. subtest = 0;
  103. errno = 0; if (!getitimer(-1, &it) || errno != EINVAL) my_e(1);
  104. errno = 0; if ( getitimer(timer, &it) ) my_e(2);
  105. errno = 0; if (!getitimer( 3, &it) || errno != EINVAL) my_e(3);
  106. }
  107. /* test if we get back what we set */
  108. void test_getset()
  109. {
  110. struct itimerval it, oit;
  111. subtest = 1;
  112. /* no alarm should be set initially */
  113. if (getitimer(timer, &it)) my_e(1);
  114. if (!EQITIMER(it, 0, 0, 0, 0)) my_e(2);
  115. if (setitimer(timer, &it, &oit)) my_e(3);
  116. if (setitimer(timer, &oit, NULL)) my_e(4);
  117. if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(5);
  118. FILLITIMER(it, 123, 0, 456, 0);
  119. if (setitimer(timer, &it, NULL)) my_e(6);
  120. FILLITIMER(it, 987, 0, 654, 0);
  121. if (setitimer(timer, &it, &oit)) my_e(7);
  122. if (!LEITIMER(oit, 123, 0, 456, 0)) my_e(8);
  123. if (getitimer(timer, &oit)) my_e(9);
  124. if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(10);
  125. FILLITIMER(it, 0, 0, 0, 0);
  126. if (setitimer(timer, &it, &oit)) my_e(11);
  127. if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(12);
  128. if (getitimer(timer, &oit)) my_e(13);
  129. if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(14);
  130. }
  131. /* test negative/large values */
  132. void test_neglarge()
  133. {
  134. struct itimerval it;
  135. subtest = 2;
  136. FILLITIMER(it, 4, 0, 5, 0);
  137. if (setitimer(timer, &it, NULL)) my_e(1);
  138. FILLITIMER(it, 1000000000, 0, 0, 0);
  139. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(2);
  140. FILLITIMER(it, 0, 1000000, 0, 0);
  141. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(3);
  142. FILLITIMER(it, 0, 0, 0, 1000000);
  143. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(4);
  144. FILLITIMER(it, -1, 0, 0, 0);
  145. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(5);
  146. FILLITIMER(it, 0, -1, 0, 0);
  147. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(6);
  148. FILLITIMER(it, 0, 0, -1, 0);
  149. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(7);
  150. FILLITIMER(it, 0, 0, 0, -1);
  151. if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(8);
  152. if (getitimer(timer, &it)) my_e(9);
  153. if (!LEITIMER(it, 4, 0, 5, 0)) my_e(10);
  154. }
  155. /* setitimer with a zero timer has to set the interval to zero as well */
  156. void test_zero()
  157. {
  158. struct itimerval it;
  159. subtest = 3;
  160. it.it_value.tv_sec = 0;
  161. it.it_value.tv_usec = 0;
  162. it.it_interval.tv_sec = 1;
  163. it.it_interval.tv_usec = 1;
  164. if (setitimer(timer, &it, NULL)) my_e(1);
  165. if (getitimer(timer, &it)) my_e(2);
  166. if (!EQITIMER(it, 0, 0, 0, 0)) my_e(3);
  167. }
  168. /* test actual timer functioning */
  169. void test_timer()
  170. {
  171. struct itimerval it;
  172. subtest = 4;
  173. if (signal(sigs[timer], got_alarm) == SIG_ERR) my_e(1);
  174. FILLITIMER(it, 0, 100000, 0, 100000);
  175. if (setitimer(timer, &it, NULL)) my_e(2);
  176. signals = 0;
  177. busy_wait(1);
  178. FILLITIMER(it, 0, 0, 0, 0);
  179. if (setitimer(timer, &it, NULL)) my_e(3);
  180. /* we don't know how many signals we'll actually get in practice,
  181. * so these checks more or less cover the extremes of the acceptable */
  182. if (signals < 2) my_e(4);
  183. if (signals > system_hz * 2) my_e(5);
  184. /* only for REAL timer can we check against the clock */
  185. if (timer == ITIMER_REAL) {
  186. FILLITIMER(it, 1, 0, 0, 0);
  187. if (setitimer(timer, &it, NULL)) my_e(6);
  188. signals = 0;
  189. busy_wait(1);
  190. FILLITIMER(it, 0, 0, 0, 0);
  191. if (setitimer(timer, &it, NULL)) my_e(7);
  192. if (signals != 1) my_e(8);
  193. }
  194. signals = 0;
  195. busy_wait(1);
  196. if (signals != 0) my_e(9);
  197. }
  198. /* test itimer/alarm interaction */
  199. void test_alarm(void) {
  200. struct itimerval it;
  201. /* only applicable for ITIMER_REAL */
  202. if (timer != ITIMER_REAL) return;
  203. subtest = 5;
  204. if (signal(SIGALRM, got_alarm) == SIG_ERR) my_e(1);
  205. FILLITIMER(it, 3, 0, 1, 0);
  206. if (setitimer(timer, &it, NULL)) my_e(2);
  207. if (alarm(2) != 3) my_e(3);
  208. if (getitimer(timer, &it)) my_e(4);
  209. if (!LEITIMER(it, 2, 0, 0, 0)) my_e(5);
  210. signals = 0;
  211. busy_wait(5);
  212. if (signals != 1) my_e(6);
  213. if (getitimer(timer, &it)) my_e(7);
  214. if (!EQITIMER(it, 0, 0, 0, 0)) my_e(8);
  215. }
  216. /* test that the timer is reset on forking */
  217. void test_fork(void) {
  218. struct itimerval it, oit;
  219. pid_t pid;
  220. int status;
  221. subtest = 6;
  222. FILLITIMER(it, 12, 34, 56, 78);
  223. if (setitimer(timer, &it, NULL)) my_e(1);
  224. pid = fork();
  225. if (pid < 0) my_e(2);
  226. if (pid == 0) {
  227. if (getitimer(timer, &it)) exit(5);
  228. if (!EQITIMER(it, 0, 0, 0, 0)) exit(6);
  229. exit(0);
  230. }
  231. if (wait(&status) != pid) my_e(3);
  232. if (!WIFEXITED(status)) my_e(4);
  233. if (WEXITSTATUS(status) != 0) my_e(WEXITSTATUS(status));
  234. FILLITIMER(it, 0, 0, 0, 0);
  235. if (setitimer(timer, &it, &oit)) my_e(7);
  236. if (!LEITIMER(oit, 12, 34, 56, 78)) my_e(8);
  237. }
  238. /* test if timer is carried over to exec()'ed process */
  239. void test_exec(void) {
  240. struct itimerval it;
  241. pid_t pid;
  242. int status;
  243. char buf[2];
  244. subtest = 7;
  245. pid = fork();
  246. if (pid < 0) my_e(1);
  247. if (pid == 0) {
  248. FILLITIMER(it, 3, 0, 1, 0);
  249. if (setitimer(timer, &it, NULL)) exit(2);
  250. sprintf(buf, "%d", timer);
  251. execl(executable, "DO CHECK", buf, NULL);
  252. exit(3);
  253. }
  254. if (wait(&status) != pid) my_e(4);
  255. if (WIFSIGNALED(status)) {
  256. /* process should have died from corresponding signal */
  257. if (WTERMSIG(status) != sigs[timer]) my_e(5);
  258. }
  259. else {
  260. if (WIFEXITED(status)) my_e(WEXITSTATUS(status));
  261. else my_e(6);
  262. }
  263. }
  264. /* procedure of the exec()'ed process */
  265. int do_check()
  266. {
  267. struct itimerval it;
  268. if (getitimer(timer, &it)) return(81);
  269. if (!LEITIMER(it, 3, 0, 1, 0)) return(82);
  270. busy_wait(60);
  271. return(83);
  272. }
  273. void busy_wait(secs)
  274. int secs;
  275. {
  276. time_t now, exp;
  277. int i;
  278. exp = time(&now) + secs + 1;
  279. while (now < exp) {
  280. for (i = 0; i < 100000; i++);
  281. time(&now);
  282. }
  283. }
  284. void got_alarm(sig)
  285. int sig;
  286. {
  287. if (sig != sigs[timer]) my_e(1001);
  288. signals++;
  289. }