From patchwork Sun Apr 7 19:33:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Crowe X-Patchwork-Id: 32181 Received: (qmail 81439 invoked by alias); 7 Apr 2019 19:34:32 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 81376 invoked by uid 89); 7 Apr 2019 19:34:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy=third, join, 4226, 0.3 X-HELO: avasout02.plus.net X-CM-Score: 0.00 From: Mike Crowe To: libc-alpha@sourceware.org Cc: Mike Crowe Subject: [PATCH v2 5/6] nptl: Convert some rwlock tests to use libsupport Date: Sun, 7 Apr 2019 20:33:54 +0100 Message-Id: <421ec9ff5f531a4df059fdec8dba4c66e531edea.1554665560.git-series.mac@mcrowe.com> In-Reply-To: References: In-Reply-To: References: * nptl/tst-rwlock6.c: Fix small bug in timeout-checking code that could erroneously pass if the function incorrectly took more than a second. * nptl/tst-rwlock6.c: Use clock_gettime(2) rather than gettimeofday(2) and then converting to timespec in preparation for testing pthread_rwlock_clockrdclock and pthread_rwlock_clockwrlock. * nptl/tst-rwlock7.c, nptl/tst-rwlock9.c: Likewise. * support/check.h: Introduce FAIL_THREAD_EXIT1 and FAIL_PRINT macros. * nptl/tst-rwlock6.c, nptl/tst-rwlock7.c, nptl/tst-rwlock9.c, nptl/tst-rwlock14.c: Use libsupport. --- ChangeLog | 10 +++- nptl/tst-rwlock14.c | 122 +++++--------------------------------- nptl/tst-rwlock6.c | 146 ++++++++------------------------------------- nptl/tst-rwlock7.c | 119 ++++++++----------------------------- nptl/tst-rwlock9.c | 96 ++++++------------------------ 5 files changed, 107 insertions(+), 386 deletions(-) diff --git a/ChangeLog b/ChangeLog index c78863e..929018e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2019-04-06 Mike Crowe + * nptl/tst-rwlock6.c: Use libsupport. This also happens to fix a + small bug where only tv.tv_usec was checked which could cause an + erroneous pass if pthread_rwlock_timedrdlock incorrectly took more + than a second. + + * nptl/tst-rwlock7.c, nptl/tst-rwlock9.c, nptl/tst-rwlock14.c: Use + libsupport. + +2019-04-06 Mike Crowe + * nptl/tst-sem5.c(do_test): Use xclock_gettime, timespec_add and TEST_TIMESPEC_NOW_OR_AFTER from libsupport. diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c index 6f57169..af176b6 100644 --- a/nptl/tst-rwlock14.c +++ b/nptl/tst-rwlock14.c @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include static pthread_barrier_t b; @@ -31,18 +34,14 @@ static void * tf (void *arg) { /* Lock the read-write lock. */ - if (pthread_rwlock_wrlock (&r) != 0) - { - puts ("tf: cannot lock rwlock"); - exit (EXIT_FAILURE); - } + TEST_COMPARE (pthread_rwlock_wrlock (&r), 0); pthread_t mt = *(pthread_t *) arg; - pthread_barrier_wait (&b); + xpthread_barrier_wait (&b); /* This call will never return. */ - pthread_join (mt, NULL); + xpthread_join (mt); return NULL; } @@ -51,118 +50,35 @@ tf (void *arg) static int do_test (void) { - int result = 0; struct timespec ts; - if (clock_gettime (CLOCK_REALTIME, &ts) != 0) - { - puts ("clock_gettime failed"); - return 1; - } - - if (pthread_barrier_init (&b, NULL, 2) != 0) - { - puts ("barrier_init failed"); - return 1; - } + xclock_gettime (CLOCK_REALTIME, &ts); + xpthread_barrier_init (&b, NULL, 2); pthread_t me = pthread_self (); - pthread_t th; - if (pthread_create (&th, NULL, tf, &me) != 0) - { - puts ("create failed"); - return 1; - } + xpthread_create (NULL, tf, &me); /* Wait until the rwlock is locked. */ - pthread_barrier_wait (&b); + xpthread_barrier_wait (&b); ts.tv_nsec = -1; - int e = pthread_rwlock_timedrdlock (&r, &ts); - if (e == 0) - { - puts ("first rwlock_timedrdlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("first rwlock_timedrdlock did not return EINVAL"); - result = 1; - } - - e = pthread_rwlock_timedwrlock (&r, &ts); - if (e == 0) - { - puts ("first rwlock_timedwrlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("first rwlock_timedwrlock did not return EINVAL"); - result = 1; - } + TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL); + TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL); ts.tv_nsec = 1000000000; - e = pthread_rwlock_timedrdlock (&r, &ts); - if (e == 0) - { - puts ("second rwlock_timedrdlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("second rwlock_timedrdlock did not return EINVAL"); - result = 1; - } - - e = pthread_rwlock_timedwrlock (&r, &ts); - if (e == 0) - { - puts ("second rwlock_timedwrlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("second rwlock_timedwrlock did not return EINVAL"); - result = 1; - } + TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL); + TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL); ts.tv_nsec = (__typeof (ts.tv_nsec)) 0x100001000LL; if ((__typeof (ts.tv_nsec)) 0x100001000LL != 0x100001000LL) ts.tv_nsec = 2000000000; - e = pthread_rwlock_timedrdlock (&r, &ts); - if (e == 0) - { - puts ("third rwlock_timedrdlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("third rwlock_timedrdlock did not return EINVAL"); - result = 1; - } - - e = pthread_rwlock_timedwrlock (&r, &ts); - if (e == 0) - { - puts ("third rwlock_timedwrlock did not fail"); - result = 1; - } - else if (e != EINVAL) - { - puts ("third rwlock_timedwrlock did not return EINVAL"); - result = 1; - } - - if (result == 0) - puts ("no bugs"); - - return result; -} + TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL); + TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL); + return 0; +} -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include diff --git a/nptl/tst-rwlock6.c b/nptl/tst-rwlock6.c index 8d6c3dc..5e73f50 100644 --- a/nptl/tst-rwlock6.c +++ b/nptl/tst-rwlock6.c @@ -22,6 +22,10 @@ #include #include #include +#include +#include +#include +#include static int kind[] = @@ -38,64 +42,26 @@ tf (void *arg) pthread_rwlock_t *r = arg; /* Timeout: 0.3 secs. */ - struct timeval tv; - (void) gettimeofday (&tv, NULL); + struct timespec ts_start; + xclock_gettime (CLOCK_REALTIME, &ts_start); - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 300000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } + struct timespec ts_timeout = timespec_add (ts_start, + make_timespec (0, 300000000)); puts ("child calling timedrdlock"); - int err = pthread_rwlock_timedrdlock (r, &ts); - if (err == 0) - { - puts ("rwlock_timedrdlock returned"); - pthread_exit ((void *) 1l); - } - - if (err != ETIMEDOUT) - { - printf ("err = %s (%d), expected %s (%d)\n", - strerror (err), err, strerror (ETIMEDOUT), ETIMEDOUT); - pthread_exit ((void *) 1l); - } + TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), ETIMEDOUT); puts ("1st child timedrdlock done"); - struct timeval tv2; - (void) gettimeofday (&tv2, NULL); - - timersub (&tv2, &tv, &tv); + TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout); - if (tv.tv_usec < 200000) - { - puts ("timeout too short"); - pthread_exit ((void *) 1l); - } - - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += 10; + xclock_gettime (CLOCK_REALTIME, &ts_timeout); + ts_timeout.tv_sec += 10; /* Note that the following operation makes ts invalid. */ - ts.tv_nsec += 1000000000; + ts_timeout.tv_nsec += 1000000000; - err = pthread_rwlock_timedrdlock (r, &ts); - if (err == 0) - { - puts ("2nd timedrdlock succeeded"); - pthread_exit ((void *) 1l); - } - if (err != EINVAL) - { - puts ("2nd timedrdlock did not return EINVAL"); - pthread_exit ((void *) 1l); - } + TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), EINVAL); puts ("2nd child timedrdlock done"); @@ -113,113 +79,59 @@ do_test (void) pthread_rwlockattr_t a; if (pthread_rwlockattr_init (&a) != 0) - { - printf ("round %Zu: rwlockattr_t failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlockattr_t failed\n", cnt); if (pthread_rwlockattr_setkind_np (&a, kind[cnt]) != 0) - { - printf ("round %Zu: rwlockattr_setkind failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlockattr_setkind failed\n", cnt); if (pthread_rwlock_init (&r, &a) != 0) - { - printf ("round %Zu: rwlock_init failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_init failed\n", cnt); if (pthread_rwlockattr_destroy (&a) != 0) - { - printf ("round %Zu: rwlockattr_destroy failed\n", cnt); - exit (1); - } - - struct timeval tv; - (void) gettimeofday (&tv, NULL); + FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt); struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - + xclock_gettime (CLOCK_REALTIME, &ts); ++ts.tv_sec; /* Get a write lock. */ int e = pthread_rwlock_timedwrlock (&r, &ts); if (e != 0) - { - printf ("round %Zu: rwlock_timedwrlock failed (%d)\n", cnt, e); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_timedwrlock failed (%d)\n", cnt, e); puts ("1st timedwrlock done"); - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (CLOCK_REALTIME, &ts); ++ts.tv_sec; - e = pthread_rwlock_timedrdlock (&r, &ts); - if (e == 0) - { - puts ("timedrdlock succeeded"); - exit (1); - } - if (e != EDEADLK) - { - puts ("timedrdlock did not return EDEADLK"); - exit (1); - } + TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EDEADLK); puts ("1st timedrdlock done"); - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (CLOCK_REALTIME, &ts); ++ts.tv_sec; - e = pthread_rwlock_timedwrlock (&r, &ts); - if (e == 0) - { - puts ("2nd timedwrlock succeeded"); - exit (1); - } - if (e != EDEADLK) - { - puts ("2nd timedwrlock did not return EDEADLK"); - exit (1); - } + TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EDEADLK); puts ("2nd timedwrlock done"); pthread_t th; if (pthread_create (&th, NULL, tf, &r) != 0) - { - printf ("round %Zu: create failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: create failed\n", cnt); puts ("started thread"); void *status; if (pthread_join (th, &status) != 0) - { - printf ("round %Zu: join failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: join failed\n", cnt); if (status != NULL) - { - printf ("failure in round %Zu\n", cnt); - exit (1); - } + FAIL_EXIT1 ("failure in round %Zu\n", cnt); puts ("joined thread"); if (pthread_rwlock_destroy (&r) != 0) - { - printf ("round %Zu: rwlock_destroy failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_destroy failed\n", cnt); } return 0; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include diff --git a/nptl/tst-rwlock7.c b/nptl/tst-rwlock7.c index 4d6f561..df50f0a 100644 --- a/nptl/tst-rwlock7.c +++ b/nptl/tst-rwlock7.c @@ -22,6 +22,10 @@ #include #include #include +#include +#include +#include +#include static int kind[] = @@ -38,61 +42,24 @@ tf (void *arg) pthread_rwlock_t *r = arg; /* Timeout: 0.3 secs. */ - struct timeval tv; - (void) gettimeofday (&tv, NULL); + struct timespec ts_start; + xclock_gettime (CLOCK_REALTIME, &ts_start); + const struct timespec ts_timeout = timespec_add (ts_start, + make_timespec (0, 300000000)); - struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_nsec += 300000000; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } - - int err = pthread_rwlock_timedwrlock (r, &ts); - if (err == 0) - { - puts ("rwlock_timedwrlock returned"); - pthread_exit ((void *) 1l); - } - - if (err != ETIMEDOUT) - { - printf ("err = %s (%d), expected %s (%d)\n", - strerror (err), err, strerror (ETIMEDOUT), ETIMEDOUT); - pthread_exit ((void *) 1l); - } + TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_timeout), ETIMEDOUT); puts ("child: timedwrlock failed with ETIMEDOUT"); - struct timeval tv2; - (void) gettimeofday (&tv2, NULL); - - timersub (&tv2, &tv, &tv); + TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout); - if (tv.tv_usec < 200000) - { - puts ("timeout too short"); - pthread_exit ((void *) 1l); - } - - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); - ts.tv_sec += 10; + struct timespec ts_invalid; + xclock_gettime (CLOCK_REALTIME, &ts_invalid); + ts_invalid.tv_sec += 10; /* Note that the following operation makes ts invalid. */ - ts.tv_nsec += 1000000000; + ts_invalid.tv_nsec += 1000000000; + + TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_invalid), EINVAL); - err = pthread_rwlock_timedwrlock (r, &ts); - if (err == 0) - { - puts ("2nd timedwrlock succeeded"); - pthread_exit ((void *) 1l); - } - if (err != EINVAL) - { - puts ("2nd timedwrlock did not return EINVAL"); - pthread_exit ((void *) 1l); - } puts ("child: timedwrlock failed with EINVAL"); return NULL; @@ -109,73 +76,43 @@ do_test (void) pthread_rwlockattr_t a; if (pthread_rwlockattr_init (&a) != 0) - { - printf ("round %Zu: rwlockattr_t failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlockattr_t failed\n", cnt); if (pthread_rwlockattr_setkind_np (&a, kind[cnt]) != 0) - { - printf ("round %Zu: rwlockattr_setkind failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlockattr_setkind failed\n", cnt); if (pthread_rwlock_init (&r, &a) != 0) - { - printf ("round %Zu: rwlock_init failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_init failed\n", cnt); if (pthread_rwlockattr_destroy (&a) != 0) - { - printf ("round %Zu: rwlockattr_destroy failed\n", cnt); - exit (1); - } - - struct timeval tv; - (void) gettimeofday (&tv, NULL); + FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt); struct timespec ts; - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (CLOCK_REALTIME, &ts); ++ts.tv_sec; /* Get a read lock. */ if (pthread_rwlock_timedrdlock (&r, &ts) != 0) - { - printf ("round %Zu: rwlock_timedrdlock failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt); + printf ("%zu: got timedrdlock\n", cnt); pthread_t th; if (pthread_create (&th, NULL, tf, &r) != 0) - { - printf ("round %Zu: create failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: create failed\n", cnt); void *status; if (pthread_join (th, &status) != 0) - { - printf ("round %Zu: join failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: join failed\n", cnt); if (status != NULL) - { - printf ("failure in round %Zu\n", cnt); - exit (1); - } + FAIL_EXIT1 ("failure in round %Zu\n", cnt); if (pthread_rwlock_destroy (&r) != 0) - { - printf ("round %Zu: rwlock_destroy failed\n", cnt); - exit (1); - } + FAIL_EXIT1 ("round %Zu: rwlock_destroy failed\n", cnt); } return 0; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include diff --git a/nptl/tst-rwlock9.c b/nptl/tst-rwlock9.c index 34f2d04..9dc126b 100644 --- a/nptl/tst-rwlock9.c +++ b/nptl/tst-rwlock9.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #define NWRITERS 15 @@ -31,8 +33,8 @@ #define NREADERS 15 #define READTRIES 15 -#define TIMEOUT 1000000 -#define DELAY 1000000 +static const struct timespec timeout = {0,1000000}; +static const struct timespec delay = {0, 1000000}; #ifndef KIND # define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP @@ -45,36 +47,23 @@ static void * writer_thread (void *nr) { struct timespec ts; - struct timespec delay; int n; - delay.tv_sec = 0; - delay.tv_nsec = DELAY; - for (n = 0; n < WRITETRIES; ++n) { int e; do { - struct timeval tv; - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (CLOCK_REALTIME, &ts); - ts.tv_nsec += 2 * TIMEOUT; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } + ts = timespec_add (ts, timeout); + ts = timespec_add (ts, timeout); printf ("writer thread %ld tries again\n", (long int) nr); e = pthread_rwlock_timedwrlock (&lock, &ts); if (e != 0 && e != ETIMEDOUT) - { - puts ("timedwrlock failed"); - exit (1); - } + FAIL_EXIT1 ("timedwrlock failed"); } while (e == ETIMEDOUT); @@ -83,10 +72,7 @@ writer_thread (void *nr) nanosleep (&delay, NULL); if (pthread_rwlock_unlock (&lock) != 0) - { - puts ("unlock for writer failed"); - exit (1); - } + FAIL_EXIT1 ("unlock for writer failed"); printf ("writer thread %ld released\n", (long int) nr); } @@ -99,36 +85,22 @@ static void * reader_thread (void *nr) { struct timespec ts; - struct timespec delay; int n; - delay.tv_sec = 0; - delay.tv_nsec = DELAY; - for (n = 0; n < READTRIES; ++n) { int e; do { - struct timeval tv; - (void) gettimeofday (&tv, NULL); - TIMEVAL_TO_TIMESPEC (&tv, &ts); + xclock_gettime (CLOCK_REALTIME, &ts); - ts.tv_nsec += TIMEOUT; - if (ts.tv_nsec >= 1000000000) - { - ts.tv_nsec -= 1000000000; - ++ts.tv_sec; - } + ts = timespec_add (ts, timeout); printf ("reader thread %ld tries again\n", (long int) nr); e = pthread_rwlock_timedrdlock (&lock, &ts); if (e != 0 && e != ETIMEDOUT) - { - puts ("timedrdlock failed"); - exit (1); - } + FAIL_EXIT1 ("timedrdlock failed"); } while (e == ETIMEDOUT); @@ -137,10 +109,7 @@ reader_thread (void *nr) nanosleep (&delay, NULL); if (pthread_rwlock_unlock (&lock) != 0) - { - puts ("unlock for reader failed"); - exit (1); - } + FAIL_EXIT1 ("unlock for reader failed"); printf ("reader thread %ld released\n", (long int) nr); } @@ -159,22 +128,13 @@ do_test (void) pthread_rwlockattr_t a; if (pthread_rwlockattr_init (&a) != 0) - { - puts ("rwlockattr_t failed"); - exit (1); - } + FAIL_EXIT1 ("rwlockattr_t failed"); if (pthread_rwlockattr_setkind_np (&a, KIND) != 0) - { - puts ("rwlockattr_setkind failed"); - exit (1); - } + FAIL_EXIT1 ("rwlockattr_setkind failed"); if (pthread_rwlock_init (&lock, &a) != 0) - { - puts ("rwlock_init failed"); - exit (1); - } + FAIL_EXIT1 ("rwlock_init failed"); /* Make standard error the same as standard output. */ dup2 (1, 2); @@ -185,37 +145,23 @@ do_test (void) for (n = 0; n < NWRITERS; ++n) if (pthread_create (&thwr[n], NULL, writer_thread, (void *) (long int) n) != 0) - { - puts ("writer create failed"); - exit (1); - } + FAIL_EXIT1 ("writer create failed"); for (n = 0; n < NREADERS; ++n) if (pthread_create (&thrd[n], NULL, reader_thread, (void *) (long int) n) != 0) - { - puts ("reader create failed"); - exit (1); - } + FAIL_EXIT1 ("reader create failed"); /* Wait for all the threads. */ for (n = 0; n < NWRITERS; ++n) if (pthread_join (thwr[n], &res) != 0) - { - puts ("writer join failed"); - exit (1); - } + FAIL_EXIT1 ("writer join failed"); for (n = 0; n < NREADERS; ++n) if (pthread_join (thrd[n], &res) != 0) - { - puts ("reader join failed"); - exit (1); - } + FAIL_EXIT1 ("reader join failed"); return 0; } -#undef TIMEOUT #define TIMEOUT 30 -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include