tst-timer4.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. /* Tests for POSIX timer implementation.
  2. Copyright (C) 2004-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public License as
  6. published by the Free Software Foundation; either version 2.1 of the
  7. License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; see the file COPYING.LIB. If
  14. not, see <https://www.gnu.org/licenses/>. */
  15. #include <errno.h>
  16. #include <signal.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <time.h>
  20. #include <unistd.h>
  21. #include <stdint.h>
  22. #if _POSIX_THREADS && defined SA_SIGINFO
  23. # include <pthread.h>
  24. # ifndef TEST_CLOCK
  25. # define TEST_CLOCK CLOCK_REALTIME
  26. # endif
  27. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  28. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  29. timer_t timer_none, timer_sig1, timer_sig2, timer_thr1, timer_thr2;
  30. int thr1_cnt, thr1_err;
  31. union sigval thr1_sigval;
  32. struct timespec thr1_ts;
  33. static void
  34. thr1 (union sigval sigval)
  35. {
  36. pthread_mutex_lock (&lock);
  37. thr1_err = clock_gettime (TEST_CLOCK, &thr1_ts);
  38. if (thr1_cnt >= 5)
  39. {
  40. struct itimerspec it = { };
  41. thr1_err |= timer_settime (timer_thr1, 0, &it, NULL);
  42. }
  43. thr1_sigval = sigval;
  44. ++thr1_cnt;
  45. pthread_cond_signal (&cond);
  46. pthread_mutex_unlock (&lock);
  47. }
  48. int thr2_cnt, thr2_err;
  49. union sigval thr2_sigval;
  50. size_t thr2_guardsize;
  51. struct timespec thr2_ts;
  52. static void
  53. thr2 (union sigval sigval)
  54. {
  55. pthread_attr_t nattr;
  56. int err = 0;
  57. size_t guardsize = -1;
  58. int ret = pthread_getattr_np (pthread_self (), &nattr);
  59. if (ret)
  60. {
  61. errno = ret;
  62. printf ("*** pthread_getattr_np failed: %m\n");
  63. err = 1;
  64. }
  65. else
  66. {
  67. ret = pthread_attr_getguardsize (&nattr, &guardsize);
  68. if (ret)
  69. {
  70. errno = ret;
  71. printf ("*** pthread_attr_getguardsize failed: %m\n");
  72. err = 1;
  73. }
  74. if (pthread_attr_destroy (&nattr) != 0)
  75. {
  76. puts ("*** pthread_attr_destroy failed");
  77. err = 1;
  78. }
  79. }
  80. pthread_mutex_lock (&lock);
  81. thr2_err = clock_gettime (TEST_CLOCK, &thr2_ts) | err;
  82. if (thr2_cnt >= 5)
  83. {
  84. struct itimerspec it = { };
  85. thr2_err |= timer_settime (timer_thr2, 0, &it, NULL);
  86. }
  87. thr2_sigval = sigval;
  88. ++thr2_cnt;
  89. thr2_guardsize = guardsize;
  90. pthread_cond_signal (&cond);
  91. pthread_mutex_unlock (&lock);
  92. }
  93. volatile int sig1_cnt, sig1_err;
  94. volatile union sigval sig1_sigval;
  95. struct timespec sig1_ts;
  96. static void
  97. sig1_handler (int sig, siginfo_t *info, void *ctx)
  98. {
  99. int err = 0;
  100. if (sig != SIGRTMIN) err |= 1 << 0;
  101. if (info->si_signo != SIGRTMIN) err |= 1 << 1;
  102. if (info->si_code != SI_TIMER) err |= 1 << 2;
  103. if (clock_gettime (TEST_CLOCK, &sig1_ts) != 0)
  104. err |= 1 << 3;
  105. if (sig1_cnt >= 5)
  106. {
  107. struct itimerspec it = { };
  108. if (timer_settime (timer_sig1, 0, &it, NULL))
  109. err |= 1 << 4;
  110. }
  111. sig1_err |= err;
  112. sig1_sigval = info->si_value;
  113. ++sig1_cnt;
  114. }
  115. volatile int sig2_cnt, sig2_err;
  116. volatile union sigval sig2_sigval;
  117. struct timespec sig2_ts;
  118. static void
  119. sig2_handler (int sig, siginfo_t *info, void *ctx)
  120. {
  121. int err = 0;
  122. if (sig != SIGRTMIN + 1) err |= 1 << 0;
  123. if (info->si_signo != SIGRTMIN + 1) err |= 1 << 1;
  124. if (info->si_code != SI_TIMER) err |= 1 << 2;
  125. if (clock_gettime (TEST_CLOCK, &sig2_ts) != 0)
  126. err |= 1 << 3;
  127. if (sig2_cnt >= 5)
  128. {
  129. struct itimerspec it = { };
  130. if (timer_settime (timer_sig2, 0, &it, NULL))
  131. err |= 1 << 4;
  132. }
  133. sig2_err |= err;
  134. sig2_sigval = info->si_value;
  135. ++sig2_cnt;
  136. }
  137. /* Check if end is later or equal to start + nsec. */
  138. static int
  139. check_ts (const char *name, const struct timespec *start,
  140. const struct timespec *end, long msec)
  141. {
  142. struct timespec ts = *start;
  143. ts.tv_sec += msec / 1000000;
  144. ts.tv_nsec += (msec % 1000000) * 1000;
  145. if (ts.tv_nsec >= 1000000000)
  146. {
  147. ++ts.tv_sec;
  148. ts.tv_nsec -= 1000000000;
  149. }
  150. if (end->tv_sec < ts.tv_sec
  151. || (end->tv_sec == ts.tv_sec && end->tv_nsec < ts.tv_nsec))
  152. {
  153. printf ("\
  154. *** timer %s invoked too soon: %ld.%09jd instead of expected %ld.%09jd\n",
  155. name, (long) end->tv_sec, (intmax_t) end->tv_nsec,
  156. (long) ts.tv_sec, (intmax_t) ts.tv_nsec);
  157. return 1;
  158. }
  159. else
  160. return 0;
  161. }
  162. #define TEST_FUNCTION do_test ()
  163. static int
  164. do_test (void)
  165. {
  166. int result = 0;
  167. #ifdef TEST_CLOCK_MISSING
  168. const char *missing = TEST_CLOCK_MISSING (TEST_CLOCK);
  169. if (missing != NULL)
  170. {
  171. printf ("%s missing, skipping test\n", missing);
  172. return 0;
  173. }
  174. #endif
  175. struct timespec ts;
  176. if (clock_gettime (TEST_CLOCK, &ts) != 0)
  177. {
  178. printf ("*** clock_gettime failed: %m\n");
  179. result = 1;
  180. }
  181. else
  182. printf ("clock_gettime returned timespec = { %ld, %jd }\n",
  183. (long) ts.tv_sec, (intmax_t) ts.tv_nsec);
  184. if (clock_getres (TEST_CLOCK, &ts) != 0)
  185. {
  186. printf ("*** clock_getres failed: %m\n");
  187. result = 1;
  188. }
  189. else
  190. printf ("clock_getres returned timespec = { %ld, %jd }\n",
  191. (long) ts.tv_sec, (intmax_t) ts.tv_nsec);
  192. struct sigevent ev;
  193. memset (&ev, 0x11, sizeof (ev));
  194. ev.sigev_notify = SIGEV_NONE;
  195. if (timer_create (TEST_CLOCK, &ev, &timer_none) != 0)
  196. {
  197. printf ("*** timer_create for timer_none failed: %m\n");
  198. return 1;
  199. }
  200. struct sigaction sa = { .sa_sigaction = sig1_handler,
  201. .sa_flags = SA_SIGINFO };
  202. sigemptyset (&sa.sa_mask);
  203. sigaction (SIGRTMIN, &sa, NULL);
  204. sa.sa_sigaction = sig2_handler;
  205. sigaction (SIGRTMIN + 1, &sa, NULL);
  206. memset (&ev, 0x22, sizeof (ev));
  207. ev.sigev_notify = SIGEV_SIGNAL;
  208. ev.sigev_signo = SIGRTMIN;
  209. ev.sigev_value.sival_ptr = &ev;
  210. if (timer_create (TEST_CLOCK, &ev, &timer_sig1) != 0)
  211. {
  212. printf ("*** timer_create for timer_sig1 failed: %m\n");
  213. return 1;
  214. }
  215. memset (&ev, 0x33, sizeof (ev));
  216. ev.sigev_notify = SIGEV_SIGNAL;
  217. ev.sigev_signo = SIGRTMIN + 1;
  218. ev.sigev_value.sival_int = 163;
  219. if (timer_create (TEST_CLOCK, &ev, &timer_sig2) != 0)
  220. {
  221. printf ("*** timer_create for timer_sig2 failed: %m\n");
  222. return 1;
  223. }
  224. memset (&ev, 0x44, sizeof (ev));
  225. ev.sigev_notify = SIGEV_THREAD;
  226. ev.sigev_notify_function = thr1;
  227. ev.sigev_notify_attributes = NULL;
  228. ev.sigev_value.sival_ptr = &ev;
  229. if (timer_create (TEST_CLOCK, &ev, &timer_thr1) != 0)
  230. {
  231. printf ("*** timer_create for timer_thr1 failed: %m\n");
  232. return 1;
  233. }
  234. pthread_attr_t nattr;
  235. if (pthread_attr_init (&nattr)
  236. || pthread_attr_setguardsize (&nattr, 0))
  237. {
  238. puts ("*** pthread_attr_t setup failed");
  239. result = 1;
  240. }
  241. memset (&ev, 0x55, sizeof (ev));
  242. ev.sigev_notify = SIGEV_THREAD;
  243. ev.sigev_notify_function = thr2;
  244. ev.sigev_notify_attributes = &nattr;
  245. ev.sigev_value.sival_int = 111;
  246. if (timer_create (TEST_CLOCK, &ev, &timer_thr2) != 0)
  247. {
  248. printf ("*** timer_create for timer_thr2 failed: %m\n");
  249. return 1;
  250. }
  251. int ret = timer_getoverrun (timer_thr1);
  252. if (ret != 0)
  253. {
  254. if (ret == -1)
  255. printf ("*** timer_getoverrun failed: %m\n");
  256. else
  257. printf ("*** timer_getoverrun returned %d != 0\n", ret);
  258. result = 1;
  259. }
  260. struct itimerspec it;
  261. it.it_value.tv_sec = 0;
  262. it.it_value.tv_nsec = -26;
  263. it.it_interval.tv_sec = 0;
  264. it.it_interval.tv_nsec = 0;
  265. if (timer_settime (timer_sig1, 0, &it, NULL) == 0)
  266. {
  267. puts ("*** timer_settime with negative tv_nsec unexpectedly succeeded");
  268. result = 1;
  269. }
  270. else if (errno != EINVAL)
  271. {
  272. printf ("*** timer_settime with negative tv_nsec did not fail with "
  273. "EINVAL: %m\n");
  274. result = 1;
  275. }
  276. it.it_value.tv_nsec = 100000;
  277. it.it_interval.tv_nsec = 1000000000;
  278. if (timer_settime (timer_sig2, 0, &it, NULL) == 0)
  279. {
  280. puts ("\
  281. *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
  282. result = 1;
  283. }
  284. else if (errno != EINVAL)
  285. {
  286. printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
  287. "EINVAL: %m\n");
  288. result = 1;
  289. }
  290. #if 0
  291. it.it_value.tv_nsec = 0;
  292. it.it_interval.tv_nsec = -26;
  293. if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
  294. {
  295. printf ("\
  296. !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
  297. /* FIXME: is this mandated by POSIX?
  298. result = 1; */
  299. }
  300. it.it_interval.tv_nsec = 3000000000;
  301. if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
  302. {
  303. printf ("\
  304. !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
  305. /* FIXME: is this mandated by POSIX?
  306. result = 1; */
  307. }
  308. #endif
  309. struct timespec startts;
  310. if (clock_gettime (TEST_CLOCK, &startts) != 0)
  311. {
  312. printf ("*** clock_gettime failed: %m\n");
  313. result = 1;
  314. }
  315. it.it_value.tv_nsec = 100000000;
  316. it.it_interval.tv_nsec = 0;
  317. if (timer_settime (timer_none, 0, &it, NULL) != 0)
  318. {
  319. printf ("*** timer_settime timer_none failed: %m\n");
  320. result = 1;
  321. }
  322. it.it_value.tv_nsec = 200000000;
  323. if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
  324. {
  325. printf ("*** timer_settime timer_thr1 failed: %m\n");
  326. result = 1;
  327. }
  328. it.it_value.tv_nsec = 300000000;
  329. if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
  330. {
  331. printf ("*** timer_settime timer_thr2 failed: %m\n");
  332. result = 1;
  333. }
  334. it.it_value.tv_nsec = 400000000;
  335. if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
  336. {
  337. printf ("*** timer_settime timer_sig1 failed: %m\n");
  338. result = 1;
  339. }
  340. it.it_value.tv_nsec = 500000000;
  341. if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
  342. {
  343. printf ("*** timer_settime timer_sig2 failed: %m\n");
  344. result = 1;
  345. }
  346. pthread_mutex_lock (&lock);
  347. while (thr1_cnt == 0 || thr2_cnt == 0)
  348. pthread_cond_wait (&cond, &lock);
  349. pthread_mutex_unlock (&lock);
  350. while (sig1_cnt == 0 || sig2_cnt == 0)
  351. {
  352. ts.tv_sec = 0;
  353. ts.tv_nsec = 100000000;
  354. nanosleep (&ts, NULL);
  355. }
  356. pthread_mutex_lock (&lock);
  357. if (thr1_cnt != 1)
  358. {
  359. printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt);
  360. result = 1;
  361. }
  362. else if (thr1_err)
  363. {
  364. puts ("*** an error occurred in thr1");
  365. result = 1;
  366. }
  367. else if (thr1_sigval.sival_ptr != &ev)
  368. {
  369. printf ("*** thr1_sigval.sival_ptr %p != %p\n",
  370. thr1_sigval.sival_ptr, &ev);
  371. result = 1;
  372. }
  373. else if (check_ts ("thr1", &startts, &thr1_ts, 200000))
  374. result = 1;
  375. if (thr2_cnt != 1)
  376. {
  377. printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt);
  378. result = 1;
  379. }
  380. else if (thr2_err)
  381. {
  382. puts ("*** an error occurred in thr2");
  383. result = 1;
  384. }
  385. else if (thr2_sigval.sival_int != 111)
  386. {
  387. printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval.sival_int);
  388. result = 1;
  389. }
  390. else if (check_ts ("thr2", &startts, &thr2_ts, 300000))
  391. result = 1;
  392. else if (thr2_guardsize != 0)
  393. {
  394. printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
  395. result = 1;
  396. }
  397. pthread_mutex_unlock (&lock);
  398. if (sig1_cnt != 1)
  399. {
  400. printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt);
  401. result = 1;
  402. }
  403. else if (sig1_err)
  404. {
  405. printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
  406. result = 1;
  407. }
  408. else if (sig1_sigval.sival_ptr != &ev)
  409. {
  410. printf ("*** sig1_sigval.sival_ptr %p != %p\n",
  411. sig1_sigval.sival_ptr, &ev);
  412. result = 1;
  413. }
  414. else if (check_ts ("sig1", &startts, &sig1_ts, 400000))
  415. result = 1;
  416. if (sig2_cnt != 1)
  417. {
  418. printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt);
  419. result = 1;
  420. }
  421. else if (sig2_err)
  422. {
  423. printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
  424. result = 1;
  425. }
  426. else if (sig2_sigval.sival_int != 163)
  427. {
  428. printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval.sival_int);
  429. result = 1;
  430. }
  431. else if (check_ts ("sig2", &startts, &sig2_ts, 500000))
  432. result = 1;
  433. if (timer_gettime (timer_none, &it) != 0)
  434. {
  435. printf ("*** timer_gettime timer_none failed: %m\n");
  436. result = 1;
  437. }
  438. else if (it.it_value.tv_sec || it.it_value.tv_nsec
  439. || it.it_interval.tv_sec || it.it_interval.tv_nsec)
  440. {
  441. printf ("\
  442. *** timer_gettime timer_none returned { %ld.%09jd, %ld.%09jd }\n",
  443. (long) it.it_value.tv_sec, (intmax_t) it.it_value.tv_nsec,
  444. (long) it.it_interval.tv_sec, (intmax_t) it.it_interval.tv_nsec);
  445. result = 1;
  446. }
  447. if (clock_gettime (TEST_CLOCK, &startts) != 0)
  448. {
  449. printf ("*** clock_gettime failed: %m\n");
  450. result = 1;
  451. }
  452. it.it_value.tv_sec = 1;
  453. it.it_value.tv_nsec = 0;
  454. it.it_interval.tv_sec = 0;
  455. it.it_interval.tv_nsec = 100000000;
  456. if (timer_settime (timer_none, 0, &it, NULL) != 0)
  457. {
  458. printf ("*** timer_settime timer_none failed: %m\n");
  459. result = 1;
  460. }
  461. it.it_value.tv_nsec = 100000000;
  462. it.it_interval.tv_nsec = 200000000;
  463. if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
  464. {
  465. printf ("*** timer_settime timer_thr1 failed: %m\n");
  466. result = 1;
  467. }
  468. it.it_value.tv_nsec = 200000000;
  469. it.it_interval.tv_nsec = 300000000;
  470. if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
  471. {
  472. printf ("*** timer_settime timer_thr2 failed: %m\n");
  473. result = 1;
  474. }
  475. it.it_value.tv_nsec = 300000000;
  476. it.it_interval.tv_nsec = 400000000;
  477. if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
  478. {
  479. printf ("*** timer_settime timer_sig1 failed: %m\n");
  480. result = 1;
  481. }
  482. it.it_value.tv_nsec = 400000000;
  483. it.it_interval.tv_nsec = 500000000;
  484. if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
  485. {
  486. printf ("*** timer_settime timer_sig2 failed: %m\n");
  487. result = 1;
  488. }
  489. pthread_mutex_lock (&lock);
  490. while (thr1_cnt < 6 || thr2_cnt < 6)
  491. pthread_cond_wait (&cond, &lock);
  492. pthread_mutex_unlock (&lock);
  493. while (sig1_cnt < 6 || sig2_cnt < 6)
  494. {
  495. ts.tv_sec = 0;
  496. ts.tv_nsec = 100000000;
  497. nanosleep (&ts, NULL);
  498. }
  499. pthread_mutex_lock (&lock);
  500. if (thr1_err)
  501. {
  502. puts ("*** an error occurred in thr1");
  503. result = 1;
  504. }
  505. else if (check_ts ("thr1", &startts, &thr1_ts, 1100000 + 4 * 200000))
  506. result = 1;
  507. if (thr2_err)
  508. {
  509. puts ("*** an error occurred in thr2");
  510. result = 1;
  511. }
  512. else if (check_ts ("thr2", &startts, &thr2_ts, 1200000 + 4 * 300000))
  513. result = 1;
  514. else if (thr2_guardsize != 0)
  515. {
  516. printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
  517. result = 1;
  518. }
  519. pthread_mutex_unlock (&lock);
  520. if (sig1_err)
  521. {
  522. printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
  523. result = 1;
  524. }
  525. else if (check_ts ("sig1", &startts, &sig1_ts, 1300000 + 4 * 400000))
  526. result = 1;
  527. if (sig2_err)
  528. {
  529. printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
  530. result = 1;
  531. }
  532. else if (check_ts ("sig2", &startts, &sig2_ts, 1400000 + 4 * 500000))
  533. result = 1;
  534. if (timer_gettime (timer_none, &it) != 0)
  535. {
  536. printf ("*** timer_gettime timer_none failed: %m\n");
  537. result = 1;
  538. }
  539. else if (it.it_interval.tv_sec || it.it_interval.tv_nsec != 100000000)
  540. {
  541. printf ("\
  542. !!! second timer_gettime timer_none returned it_interval %ld.%09jd\n",
  543. (long) it.it_interval.tv_sec, (intmax_t) it.it_interval.tv_nsec);
  544. /* FIXME: For now disabled.
  545. result = 1; */
  546. }
  547. if (timer_delete (timer_none) != 0)
  548. {
  549. printf ("*** timer_delete for timer_none failed: %m\n");
  550. result = 1;
  551. }
  552. if (timer_delete (timer_sig1) != 0)
  553. {
  554. printf ("*** timer_delete for timer_sig1 failed: %m\n");
  555. result = 1;
  556. }
  557. if (timer_delete (timer_sig2) != 0)
  558. {
  559. printf ("*** timer_delete for timer_sig2 failed: %m\n");
  560. result = 1;
  561. }
  562. if (timer_delete (timer_thr1) != 0)
  563. {
  564. printf ("*** timer_delete for timer_thr1 failed: %m\n");
  565. result = 1;
  566. }
  567. if (timer_delete (timer_thr2) != 0)
  568. {
  569. printf ("*** timer_delete for timer_thr2 failed: %m\n");
  570. result = 1;
  571. }
  572. return result;
  573. }
  574. #elif defined TEST_CLOCK_MISSING
  575. /* This just ensures that any functions called in TEST_CLOCK_MISSING
  576. are not diagnosed as unused. */
  577. # define TEST_FUNCTION (TEST_CLOCK_MISSING (TEST_CLOCK), 0)
  578. #else
  579. # define TEST_FUNCTION 0
  580. #endif
  581. #include "../test-skeleton.c"