tst-timer4.c 16 KB

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