X-Git-Url: http://nsz.repo.hu/git/?p=libc-test;a=blobdiff_plain;f=src%2Ffunctional%2Fpthread_mutex_pi.c;fp=src%2Ffunctional%2Fpthread_mutex_pi.c;h=3a47cec1cae1612cfa321abbe604f0759e7fc58a;hp=0000000000000000000000000000000000000000;hb=2064be16d307b6409cd518303897cd0763cfdb97;hpb=281b80f0e70fe28356c3f0ded8b86f28a5c74d0a diff --git a/src/functional/pthread_mutex_pi.c b/src/functional/pthread_mutex_pi.c new file mode 100644 index 0000000..3a47cec --- /dev/null +++ b/src/functional/pthread_mutex_pi.c @@ -0,0 +1,168 @@ +/* testing pthread mutex behaviour with various attributes */ +#include +#include +#include +#include +#include +#include "test.h" + +#define T(f) if ((r=(f))) t_error(#f " failed: %s\n", strerror(r)) +#define E(f) if (f) t_error(#f " failed: %s\n", strerror(errno)) + +static void *relock(void *arg) +{ + void **a = arg; + int r; + + T(pthread_mutex_lock(a[0])); + E(sem_post(a[1])); + *(int*)a[2] = pthread_mutex_lock(a[0]); + E(sem_post(a[1])); + + T(pthread_mutex_unlock(a[0])); + if (*(int*)a[2] == 0) + T(pthread_mutex_unlock(a[0])); + return 0; +} + +static int test_relock(int mtype) +{ + struct timespec ts; + pthread_t t; + pthread_mutex_t m; + pthread_mutexattr_t ma; + sem_t s; + int i; + int r; + void *p; + void *a[] = {&m,&s,&i}; + + T(pthread_mutexattr_init(&ma)); + T(pthread_mutexattr_settype(&ma, mtype)); + T(pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT)); + T(pthread_mutex_init(a[0], &ma)); + T(pthread_mutexattr_destroy(&ma)); + E(sem_init(a[1], 0, 0)); + T(pthread_create(&t, 0, relock, a)); + E(sem_wait(a[1])); + E(clock_gettime(CLOCK_REALTIME, &ts)); + ts.tv_nsec += 100*1000*1000; + if (ts.tv_nsec >= 1000*1000*1000) { + ts.tv_nsec -= 1000*1000*1000; + ts.tv_sec += 1; + } + r = sem_timedwait(a[1],&ts); + if (r == -1) { + if (errno != ETIMEDOUT) + t_error("sem_timedwait failed with unexpected error: %s\n", strerror(errno)); + /* leave the deadlocked relock thread running */ + return -1; + } + T(pthread_join(t, &p)); + T(pthread_mutex_destroy(a[0])); + E(sem_destroy(a[1])); + return i; +} + +static void *unlock(void *arg) +{ + void **a = arg; + + *(int*)a[1] = pthread_mutex_unlock(a[0]); + return 0; +} + +static int test_unlock(int mtype) +{ + pthread_t t; + pthread_mutex_t m; + pthread_mutexattr_t ma; + int i; + int r; + void *p; + void *a[] = {&m,&i}; + + T(pthread_mutexattr_init(&ma)); + T(pthread_mutexattr_settype(&ma, mtype)); + T(pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT)); + T(pthread_mutex_init(a[0], &ma)); + T(pthread_mutexattr_destroy(&ma)); + T(pthread_create(&t, 0, unlock, a)); + T(pthread_join(t, &p)); + T(pthread_mutex_destroy(a[0])); + return i; +} + +static int test_unlock_other(int mtype) +{ + pthread_t t; + pthread_mutex_t m; + pthread_mutexattr_t ma; + int i; + int r; + void *p; + void *a[] = {&m,&i}; + + T(pthread_mutexattr_init(&ma)); + T(pthread_mutexattr_settype(&ma, mtype)); + T(pthread_mutexattr_setprotocol(&ma, PTHREAD_PRIO_INHERIT)); + T(pthread_mutex_init(a[0], &ma)); + T(pthread_mutexattr_destroy(&ma)); + T(pthread_mutex_lock(a[0])); + T(pthread_create(&t, 0, unlock, a)); + T(pthread_join(t, &p)); + T(pthread_mutex_unlock(a[0])); + T(pthread_mutex_destroy(a[0])); + return i; +} + +static void test_mutexattr() +{ + pthread_mutex_t m; + pthread_mutexattr_t a; + int r; + int i; + + T(pthread_mutexattr_init(&a)); + T(pthread_mutexattr_gettype(&a, &i)); + if (i != PTHREAD_MUTEX_DEFAULT) + t_error("default mutex type is %d, wanted PTHREAD_MUTEX_DEFAULT (%d)\n", i, PTHREAD_MUTEX_DEFAULT); + T(pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK)); + T(pthread_mutexattr_gettype(&a, &i)); + if (i != PTHREAD_MUTEX_ERRORCHECK) + t_error("setting error check mutex type failed failed: got %d, wanted %d\n", i, PTHREAD_MUTEX_ERRORCHECK); + T(pthread_mutexattr_destroy(&a)); +} + +int main(void) +{ + int i; + + test_mutexattr(); + + i = test_relock(PTHREAD_MUTEX_NORMAL); + if (i != -1) + t_error("PTHREAD_MUTEX_NORMAL relock did not deadlock, got %s\n", strerror(i)); + i = test_relock(PTHREAD_MUTEX_ERRORCHECK); + if (i != EDEADLK) + t_error("PTHREAD_MUTEX_ERRORCHECK relock did not return EDEADLK, got %s\n", i==-1?"deadlock":strerror(i)); + i = test_relock(PTHREAD_MUTEX_RECURSIVE); + if (i != 0) + t_error("PTHREAD_MUTEX_RECURSIVE relock did not succed, got %s\n", i==-1?"deadlock":strerror(i)); + + i = test_unlock(PTHREAD_MUTEX_ERRORCHECK); + if (i != EPERM) + t_error("PTHREAD_MUTEX_ERRORCHECK unlock did not return EPERM, got %s\n", strerror(i)); + i = test_unlock(PTHREAD_MUTEX_RECURSIVE); + if (i != EPERM) + t_error("PTHREAD_MUTEX_RECURSIVE unlock did not return EPERM, got %s\n", strerror(i)); + + i = test_unlock_other(PTHREAD_MUTEX_ERRORCHECK); + if (i != EPERM) + t_error("PTHREAD_MUTEX_ERRORCHECK unlock did not return EPERM, got %s\n", strerror(i)); + i = test_unlock_other(PTHREAD_MUTEX_RECURSIVE); + if (i != EPERM) + t_error("PTHREAD_MUTEX_RECURSIVE unlock did not return EPERM, got %s\n", strerror(i)); + + return t_status; +}