|
Szabolcs Nagy |
47997c |
/* testing pthread mutex behaviour with various attributes */
|
|
Szabolcs Nagy |
47997c |
#include <pthread.h>
|
|
Szabolcs Nagy |
47997c |
#include <semaphore.h>
|
|
Szabolcs Nagy |
47997c |
#include <stdio.h>
|
|
Szabolcs Nagy |
47997c |
#include <errno.h>
|
|
Szabolcs Nagy |
47997c |
#include <string.h>
|
|
Szabolcs Nagy |
47997c |
#include "test.h"
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
#define T(f) if ((r=(f))) t_error(#f " failed: %s\n", strerror(r))
|
|
Szabolcs Nagy |
47997c |
#define E(f) if (f) t_error(#f " failed: %s\n", strerror(errno))
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static void *relock(void *arg)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
void **a = arg;
|
|
Szabolcs Nagy |
47997c |
int r;
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_lock(a[0]));
|
|
Szabolcs Nagy |
47997c |
E(sem_post(a[1]));
|
|
Szabolcs Nagy |
47997c |
*(int*)a[2] = pthread_mutex_lock(a[0]);
|
|
Szabolcs Nagy |
47997c |
E(sem_post(a[1]));
|
|
Szabolcs Nagy |
52dd4c |
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutex_unlock(a[0]));
|
|
Szabolcs Nagy |
52dd4c |
if (*(int*)a[2] == 0)
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutex_unlock(a[0]));
|
|
Szabolcs Nagy |
47997c |
return 0;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static int test_relock(int mtype)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
struct timespec ts;
|
|
Szabolcs Nagy |
47997c |
pthread_t t;
|
|
Szabolcs Nagy |
47997c |
pthread_mutex_t m;
|
|
Szabolcs Nagy |
47997c |
pthread_mutexattr_t ma;
|
|
Szabolcs Nagy |
47997c |
sem_t s;
|
|
Szabolcs Nagy |
47997c |
int i;
|
|
Szabolcs Nagy |
47997c |
int r;
|
|
Szabolcs Nagy |
47997c |
void *p;
|
|
Szabolcs Nagy |
47997c |
void *a[] = {&m,&s,&i};
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_init(&ma);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_settype(&ma, mtype));
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_init(a[0], &ma);;
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutexattr_destroy(&ma);;
|
|
Szabolcs Nagy |
47997c |
E(sem_init(a[1], 0, 0));
|
|
Szabolcs Nagy |
47997c |
T(pthread_create(&t, 0, relock, a));
|
|
Szabolcs Nagy |
47997c |
E(sem_wait(a[1]));
|
|
Szabolcs Nagy |
47997c |
E(clock_gettime(CLOCK_REALTIME, &ts);;
|
|
Szabolcs Nagy |
47997c |
ts.tv_nsec += 100*1000*1000;
|
|
Szabolcs Nagy |
47997c |
if (ts.tv_nsec >= 1000*1000*1000) {
|
|
Szabolcs Nagy |
47997c |
ts.tv_nsec -= 1000*1000*1000;
|
|
Szabolcs Nagy |
47997c |
ts.tv_sec += 1;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
r = sem_timedwait(a[1],&ts);
|
|
Szabolcs Nagy |
47997c |
if (r == -1) {
|
|
Szabolcs Nagy |
47997c |
if (errno != ETIMEDOUT)
|
|
Szabolcs Nagy |
47997c |
t_error("sem_timedwait failed with unexpected error: %s\n", strerror(errno));
|
|
Szabolcs Nagy |
52dd4c |
/* leave the deadlocked relock thread running */
|
|
Szabolcs Nagy |
47997c |
return -1;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
T(pthread_join(t, &p);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_destroy(a[0]));
|
|
Szabolcs Nagy |
47997c |
E(sem_destroy(a[1]));
|
|
Szabolcs Nagy |
47997c |
return i;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static void *unlock(void *arg)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
void **a = arg;
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
*(int*)a[1] = pthread_mutex_unlock(a[0]);
|
|
Szabolcs Nagy |
47997c |
return 0;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static int test_unlock(int mtype)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
pthread_t t;
|
|
Szabolcs Nagy |
47997c |
pthread_mutex_t m;
|
|
Szabolcs Nagy |
47997c |
pthread_mutexattr_t ma;
|
|
Szabolcs Nagy |
47997c |
int i;
|
|
Szabolcs Nagy |
47997c |
int r;
|
|
Szabolcs Nagy |
47997c |
void *p;
|
|
Szabolcs Nagy |
47997c |
void *a[] = {&m,&i};
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_init(&ma);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_settype(&ma, mtype));
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_init(a[0], &ma);;
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutexattr_destroy(&ma);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_create(&t, 0, unlock, a));
|
|
Szabolcs Nagy |
47997c |
T(pthread_join(t, &p);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_destroy(a[0]));
|
|
Szabolcs Nagy |
47997c |
return i;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static int test_unlock_other(int mtype)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
pthread_t t;
|
|
Szabolcs Nagy |
47997c |
pthread_mutex_t m;
|
|
Szabolcs Nagy |
47997c |
pthread_mutexattr_t ma;
|
|
Szabolcs Nagy |
47997c |
int i;
|
|
Szabolcs Nagy |
47997c |
int r;
|
|
Szabolcs Nagy |
47997c |
void *p;
|
|
Szabolcs Nagy |
47997c |
void *a[] = {&m,&i};
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_init(&ma);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_settype(&ma, mtype));
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_init(a[0], &ma);;
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutexattr_destroy(&ma);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_lock(a[0]));
|
|
Szabolcs Nagy |
47997c |
T(pthread_create(&t, 0, unlock, a));
|
|
Szabolcs Nagy |
47997c |
T(pthread_join(t, &p);;
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutex_unlock(a[0]));
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutex_destroy(a[0]));
|
|
Szabolcs Nagy |
47997c |
return i;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
static void test_mutexattr()
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
pthread_mutex_t m;
|
|
Szabolcs Nagy |
47997c |
pthread_mutexattr_t a;
|
|
Szabolcs Nagy |
47997c |
int r;
|
|
Szabolcs Nagy |
47997c |
int i;
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_init(&a);;
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_gettype(&a, &i);;
|
|
Szabolcs Nagy |
47997c |
if (i != PTHREAD_MUTEX_DEFAULT)
|
|
Szabolcs Nagy |
47997c |
t_error("default mutex type is %d, wanted PTHREAD_MUTEX_DEFAULT (%d)\n", i, PTHREAD_MUTEX_DEFAULT);
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_settype(&a, PTHREAD_MUTEX_ERRORCHECK));
|
|
Szabolcs Nagy |
47997c |
T(pthread_mutexattr_gettype(&a, &i);;
|
|
Szabolcs Nagy |
47997c |
if (i != PTHREAD_MUTEX_ERRORCHECK)
|
|
Szabolcs Nagy |
47997c |
t_error("setting error check mutex type failed failed: got %d, wanted %d\n", i, PTHREAD_MUTEX_ERRORCHECK);
|
|
Szabolcs Nagy |
52dd4c |
T(pthread_mutexattr_destroy(&a);;
|
|
Szabolcs Nagy |
47997c |
}
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
int main(void)
|
|
Szabolcs Nagy |
47997c |
{
|
|
Szabolcs Nagy |
47997c |
int i;
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
test_mutexattr();
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
i = test_relock(PTHREAD_MUTEX_NORMAL);
|
|
Szabolcs Nagy |
47997c |
if (i != -1)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_NORMAL relock did not deadlock, got %s\n", strerror(i));
|
|
Szabolcs Nagy |
47997c |
i = test_relock(PTHREAD_MUTEX_ERRORCHECK);
|
|
Szabolcs Nagy |
47997c |
if (i != EDEADLK)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_ERRORCHECK relock did not return EDEADLK, got %s\n", i==-1?"deadlock":strerror(i));
|
|
Szabolcs Nagy |
47997c |
i = test_relock(PTHREAD_MUTEX_RECURSIVE);
|
|
Szabolcs Nagy |
47997c |
if (i != 0)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_RECURSIVE relock did not succed, got %s\n", i==-1?"deadlock":strerror(i));
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
i = test_unlock(PTHREAD_MUTEX_ERRORCHECK);
|
|
Szabolcs Nagy |
47997c |
if (i != EPERM)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_ERRORCHECK unlock did not return EPERM, got %s\n", strerror(i));
|
|
Szabolcs Nagy |
47997c |
i = test_unlock(PTHREAD_MUTEX_RECURSIVE);
|
|
Szabolcs Nagy |
47997c |
if (i != EPERM)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_RECURSIVE unlock did not return EPERM, got %s\n", strerror(i));
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
i = test_unlock_other(PTHREAD_MUTEX_ERRORCHECK);
|
|
Szabolcs Nagy |
47997c |
if (i != EPERM)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_ERRORCHECK unlock did not return EPERM, got %s\n", strerror(i));
|
|
Szabolcs Nagy |
47997c |
i = test_unlock_other(PTHREAD_MUTEX_RECURSIVE);
|
|
Szabolcs Nagy |
47997c |
if (i != EPERM)
|
|
Szabolcs Nagy |
47997c |
t_error("PTHREAD_MUTEX_RECURSIVE unlock did not return EPERM, got %s\n", strerror(i));
|
|
Szabolcs Nagy |
47997c |
|
|
Szabolcs Nagy |
47997c |
return t_status;
|
|
Szabolcs Nagy |
47997c |
}
|