test_pthread_mutex.c revision 8e88ea54ff19a3dd2cf5f5309ff13356a41d615a
18e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/*
28e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * Copyright (C) 2010 The Android Open Source Project
38e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * All rights reserved.
48e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
58e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * Redistribution and use in source and binary forms, with or without
68e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * modification, are permitted provided that the following conditions
78e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * are met:
88e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *  * Redistributions of source code must retain the above copyright
98e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *    notice, this list of conditions and the following disclaimer.
108e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *  * Redistributions in binary form must reproduce the above copyright
118e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *    notice, this list of conditions and the following disclaimer in
128e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *    the documentation and/or other materials provided with the
138e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *    distribution.
148e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
158e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
168e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
178e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
188e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
198e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
208e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
218e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
228e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
238e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
248e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
258e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
268e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * SUCH DAMAGE.
278e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner */
288e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
298e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <pthread.h>
308e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <errno.h>
318e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <string.h>
328e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <stdarg.h>
338e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <stdio.h>
348e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#include <stdlib.h>
358e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
368e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* Posix states that EDEADLK should be returned in case a deadlock condition
378e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * is detected with a PTHREAD_MUTEX_ERRORCHECK lock() or trylock(), but
388e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * GLibc returns EBUSY instead.
398e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner */
408e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#ifdef HOST
418e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#  define ERRNO_PTHREAD_EDEADLK   EBUSY
428e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#else
438e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#  define ERRNO_PTHREAD_EDEADLK   EDEADLK
448e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#endif
458e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
468e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void __attribute__((noreturn))
478e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerpanic(const char* func, const char* format, ...)
488e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
498e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_list  args;
508e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    fprintf(stderr, "%s: ", func);
518e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_start(args, format);
528e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    vfprintf(stderr, format, args);
538e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_end(args);
548e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    fprintf(stderr, "\n");
558e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    exit(1);
568e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
578e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
588e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  PANIC(...)   panic(__FUNCTION__,__VA_ARGS__)
598e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
608e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void __attribute__((noreturn))
618e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnererror(int  errcode, const char* func, const char* format, ...)
628e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
638e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_list  args;
648e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    fprintf(stderr, "%s: ", func);
658e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_start(args, format);
668e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    vfprintf(stderr, format, args);
678e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    va_end(args);
688e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    fprintf(stderr, " error=%d: %s\n", errcode, strerror(errcode));
698e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    exit(1);
708e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
718e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
728e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* return current time in seconds as floating point value */
738e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic double
748e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnertime_now(void)
758e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
768e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    struct timespec ts[1];
778e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
788e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    clock_gettime(CLOCK_MONOTONIC, ts);
798e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    return (double)ts->tv_sec + ts->tv_nsec/1e9;
808e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
818e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
828e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void
838e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnertime_sleep(double  delay)
848e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
858e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    struct timespec ts;
868e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    int             ret;
878e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
888e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    ts.tv_sec  = (time_t)delay;
898e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    ts.tv_nsec = (long)((delay - ts.tv_sec)*1e9);
908e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
918e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do {
928e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner        ret = nanosleep(&ts, &ts);
938e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    } while (ret < 0 && errno == EINTR);
948e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
958e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
968e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  ERROR(errcode,...)   error((errcode),__FUNCTION__,__VA_ARGS__)
978e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
988e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  TZERO(cond)   \
998e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    { int _ret = (cond); if (_ret != 0) ERROR(_ret,"%d:%s", __LINE__, #cond); }
1008e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1018e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  TTRUE(cond)   \
1028e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    { if (!(cond)) PANIC("%d:%s", __LINE__, #cond); }
1038e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1048e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  TFALSE(cond)   \
1058e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    { if (!!(cond)) PANIC("%d:%s", __LINE__, #cond); }
1068e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1078e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner#define  TEXPECT_INT(cond,val) \
1088e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    { int _ret = (cond); if (_ret != (val)) PANIC("%d:%s returned %d (%d expected)", __LINE__, #cond, _ret, (val)); }
1098e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1108e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* perform a simple init/lock/unlock/destroy test on a mutex of given attributes */
1118e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_mutex_1(pthread_mutexattr_t *attr)
1128e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
1138e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    int              ret;
1148e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutex_t  lock[1];
1158e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1168e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
1178e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_lock(lock));
1188e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
1198e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
1208e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
1218e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1228e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void set_mutexattr_type(pthread_mutexattr_t *attr, int type)
1238e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
1248e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    int  newtype;
1258e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_settype(attr, type));
1268e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    newtype = ~type;
1278e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_gettype(attr, &newtype));
1288e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TEXPECT_INT(newtype,type);
1298e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
1308e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1318e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* simple init/lock/unlock/destroy on all mutex types */
1328e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_1(void)
1338e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
1348e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    int                  ret, type;
1358e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutexattr_t  attr[1];
1368e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1378e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(NULL);
1388e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1398e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* non-shared version */
1408e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1418e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
1428e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1438e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
1448e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1458e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1468e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
1478e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1488e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1498e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
1508e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1518e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1528e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
1538e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1548e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* shared version */
1558e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
1568e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED));
1578e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1588e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
1598e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1608e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1618e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
1628e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1638e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1648e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
1658e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_1(attr);
1668e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1678e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
1688e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
1698e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1708e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* perform init/trylock/unlock/destroy then init/lock/trylock/destroy */
1718e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_mutex_2(pthread_mutexattr_t *attr)
1728e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
1738e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutex_t  lock[1];
1748e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1758e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
1768e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
1778e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
1788e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
1798e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1808e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
1818e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
1828e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TEXPECT_INT(pthread_mutex_trylock(lock),EBUSY);
1838e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
1848e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
1858e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
1868e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1878e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_mutex_2_rec(pthread_mutexattr_t *attr)
1888e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
1898e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutex_t  lock[1];
1908e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1918e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
1928e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
1938e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
1948e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
1958e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
1968e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
1978e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
1988e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
1998e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
2008e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
2018e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
2028e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
2038e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2048e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_mutex_2_chk(pthread_mutexattr_t *attr)
2058e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
2068e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutex_t  lock[1];
2078e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2088e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
2098e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
2108e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
2118e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
2128e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2138e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(lock, attr));
2148e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_trylock(lock));
2158e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TEXPECT_INT(pthread_mutex_trylock(lock),ERRNO_PTHREAD_EDEADLK);
2168e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(lock));
2178e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_destroy(lock));
2188e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
2198e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2208e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_2(void)
2218e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
2228e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutexattr_t  attr[1];
2238e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2248e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2(NULL);
2258e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2268e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* non-shared version */
2278e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2288e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
2298e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2308e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
2318e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2(attr);
2328e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2338e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
2348e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2_rec(attr);
2358e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2368e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
2378e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2_chk(attr);
2388e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2398e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
2408e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2418e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* shared version */
2428e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
2438e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED));
2448e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2458e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
2468e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2(attr);
2478e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2488e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
2498e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2_rec(attr);
2508e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2518e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
2528e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_2_chk(attr);
2538e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2548e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
2558e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
2568e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2578e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner/* This is more complex example to test contention of mutexes.
2588e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * Essentially, what happens is this:
2598e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
2608e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * - main thread creates a mutex and locks it
2618e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * - it then creates thread 1 and thread 2
2628e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
2638e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * - it then record the current time, sleep for a specific 'waitDelay'
2648e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *   then unlock the mutex.
2658e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
2668e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * - thread 1 locks() the mutex. It shall be stopped for a least 'waitDelay'
2678e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *   seconds. It then unlocks the mutex.
2688e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
2698e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * - thread 2 trylocks() the mutex. In case of failure (EBUSY), it waits
2708e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *   for a small amount of time (see 'spinDelay') and tries again, until
2718e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *   it succeeds. It then unlocks the mutex.
2728e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner *
2738e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * The goal of this test is to verify that thread 1 has been stopped
2748e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * for a sufficiently long time, and that thread 2 has been spinning for
2758e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * the same minimum period. There is no guarantee as to which thread is
2768e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner * going to acquire the mutex first.
2778e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner */
2788e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnertypedef struct {
2798e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutex_t  mutex[1];
2808e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    double           t0;
2818e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    double           waitDelay;
2828e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    double           spinDelay;
2838e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner} Test3State;
2848e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2858e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void* do_mutex_test_3_t1(void* arg)
2868e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
2878e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    Test3State *s = arg;
2888e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    double      t1;
2898e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2908e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_lock(s->mutex));
2918e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    t1 = time_now();
2928e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    //DEBUG ONLY: printf("t1-s->t0=%g waitDelay=%g\n", t1-s->t0, s->waitDelay);
2938e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TTRUE((t1-s->t0) >= s->waitDelay);
2948e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(s->mutex));
2958e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    return NULL;
2968e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
2978e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
2988e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void* do_mutex_test_3_t2(void* arg)
2998e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
3008e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    Test3State *s = arg;
3018e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    double      t1;
3028e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3038e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    for (;;) {
3048e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner        int ret = pthread_mutex_trylock(s->mutex);
3058e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner        if (ret == 0)
3068e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner            break;
3078e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner        if (ret == EBUSY) {
3088e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner            time_sleep(s->spinDelay);
3098e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner            continue;
3108e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner        }
3118e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    }
3128e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    t1 = time_now();
3138e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TTRUE((t1-s->t0) >= s->waitDelay);
3148e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(s->mutex));
3158e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    return NULL;
3168e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
3178e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3188e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3198e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_mutex_3(pthread_mutexattr_t *attr, double delay)
3208e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
3218e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    Test3State  s[1];
3228e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_t   th1, th2;
3238e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    void*       dummy;
3248e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3258e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_init(s->mutex, attr));
3268e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    s->waitDelay = delay;
3278e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    s->spinDelay = delay/20.;
3288e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3298e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_lock(s->mutex));
3308e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3318e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_create(&th1, NULL, do_mutex_test_3_t1, s);
3328e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_create(&th2, NULL, do_mutex_test_3_t2, s);
3338e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3348e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    s->t0 = time_now();
3358e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    time_sleep(delay);
3368e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3378e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutex_unlock(s->mutex));
3388e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3398e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_join(th1, &dummy));
3408e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_join(th2, &dummy));
3418e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
3428e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3438e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerstatic void do_test_3(double  delay)
3448e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
3458e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    pthread_mutexattr_t  attr[1];
3468e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3478e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(NULL, delay);
3488e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3498e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* non-shared version */
3508e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3518e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
3528e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3538e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
3548e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3558e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3568e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
3578e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3588e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3598e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
3608e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3618e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3628e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
3638e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3648e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    /* shared version */
3658e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_init(attr));
3668e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED));
3678e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3688e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_NORMAL);
3698e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3708e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3718e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_RECURSIVE);
3728e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3738e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3748e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    set_mutexattr_type(attr, PTHREAD_MUTEX_ERRORCHECK);
3758e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_mutex_3(attr, delay);
3768e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3778e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    TZERO(pthread_mutexattr_destroy(attr));
3788e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
3798e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3808e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner
3818e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turnerint main(void)
3828e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner{
3838e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_1();
3848e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_2();
3858e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    do_test_3(0.1);
3868e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner    return 0;
3878e88ea54ff19a3dd2cf5f5309ff13356a41d615aDavid 'Digit' Turner}
388