1570af302Sopenharmony_ci#include <pthread.h> 2570af302Sopenharmony_ci#include <string.h> 3570af302Sopenharmony_ci#include <errno.h> 4570af302Sopenharmony_ci#include "test.h" 5570af302Sopenharmony_ci 6570af302Sopenharmony_ci#define TEST(r, f, m) ( \ 7570af302Sopenharmony_ci ((r) = (f)) == 0 || (t_error("%s failed: (pshared==%d, pi==%d) %s (" m ")\n", #f, pshared, pi, strerror(r)), 0) ) 8570af302Sopenharmony_ci#define TESTX(r, f, x, m) ( \ 9570af302Sopenharmony_ci ((r) = (f)) == (x) || (t_error("%s failed: (pshared==%d, pi==%d) got %d \"%s\" want %d \"%s\" (" m ")\n", #f, pshared, pi, r, strerror(r), x, strerror(x)), 0) ) 10570af302Sopenharmony_ci 11570af302Sopenharmony_cistatic void *start_lock(void *arg) 12570af302Sopenharmony_ci{ 13570af302Sopenharmony_ci pthread_mutex_lock(arg); 14570af302Sopenharmony_ci return 0; 15570af302Sopenharmony_ci} 16570af302Sopenharmony_ci 17570af302Sopenharmony_cistatic void *start_wait(void *arg) 18570af302Sopenharmony_ci{ 19570af302Sopenharmony_ci void **args = arg; 20570af302Sopenharmony_ci pthread_mutex_lock(args[1]); 21570af302Sopenharmony_ci pthread_barrier_wait(args[0]); 22570af302Sopenharmony_ci nanosleep(&(struct timespec){ .tv_nsec = 10000000 }, 0); 23570af302Sopenharmony_ci return 0; 24570af302Sopenharmony_ci} 25570af302Sopenharmony_ci 26570af302Sopenharmony_civoid f(int pshared, int pi) 27570af302Sopenharmony_ci{ 28570af302Sopenharmony_ci pthread_t td; 29570af302Sopenharmony_ci int r; 30570af302Sopenharmony_ci void *res; 31570af302Sopenharmony_ci pthread_barrier_t barrier2; 32570af302Sopenharmony_ci pthread_mutexattr_t mtx_a; 33570af302Sopenharmony_ci pthread_mutex_t mtx; 34570af302Sopenharmony_ci 35570af302Sopenharmony_ci TEST(r, pthread_barrier_init(&barrier2, 0, 2), "creating barrier"); 36570af302Sopenharmony_ci 37570af302Sopenharmony_ci /* Robust mutexes */ 38570af302Sopenharmony_ci TEST(r, pthread_mutexattr_init(&mtx_a), "initializing mutex attr"); 39570af302Sopenharmony_ci TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), "setting robust attribute"); 40570af302Sopenharmony_ci if (pshared) 41570af302Sopenharmony_ci TEST(r, pthread_mutexattr_setpshared(&mtx_a, PTHREAD_PROCESS_SHARED), "setting pshared attribute"); 42570af302Sopenharmony_ci if (pi) 43570af302Sopenharmony_ci TEST(r, pthread_mutexattr_setprotocol(&mtx_a, PTHREAD_PRIO_INHERIT), "setting PI attribute"); 44570af302Sopenharmony_ci TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex"); 45570af302Sopenharmony_ci TEST(r, pthread_mutex_lock(&mtx), "locking robust mutex"); 46570af302Sopenharmony_ci TEST(r, pthread_mutex_unlock(&mtx), "unlocking robust mutex"); 47570af302Sopenharmony_ci TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread"); 48570af302Sopenharmony_ci TEST(r, pthread_join(td, &res), "joining thread"); 49570af302Sopenharmony_ci TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex"); 50570af302Sopenharmony_ci TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex"); 51570af302Sopenharmony_ci TESTX(r, pthread_mutex_lock(&mtx), ENOTRECOVERABLE, "re-locking orphaned robust mutex"); 52570af302Sopenharmony_ci TEST(r, pthread_mutex_destroy(&mtx), "destroying unrecoverable mutex"); 53570af302Sopenharmony_ci 54570af302Sopenharmony_ci TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex"); 55570af302Sopenharmony_ci TEST(r, pthread_create(&td, 0, start_lock, &mtx), "failed to create thread"); 56570af302Sopenharmony_ci TEST(r, pthread_join(td, &res), "joining thread"); 57570af302Sopenharmony_ci TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, "locking orphaned robust mutex"); 58570af302Sopenharmony_ci TEST(r, pthread_mutex_consistent(&mtx), ""); 59570af302Sopenharmony_ci TEST(r, pthread_mutex_unlock(&mtx), "unlocking orphaned robust mutex"); 60570af302Sopenharmony_ci TEST(r, pthread_mutex_lock(&mtx), "re-locking orphaned robust mutex"); 61570af302Sopenharmony_ci TEST(r, pthread_mutex_destroy(&mtx), "destroying mutex"); 62570af302Sopenharmony_ci 63570af302Sopenharmony_ci TEST(r, pthread_mutex_init(&mtx, &mtx_a), ""); 64570af302Sopenharmony_ci TEST(r, pthread_create(&td, 0, start_wait, (void *[]){ &barrier2, &mtx }), ""); 65570af302Sopenharmony_ci r = pthread_barrier_wait(&barrier2); 66570af302Sopenharmony_ci if (r && r != PTHREAD_BARRIER_SERIAL_THREAD) 67570af302Sopenharmony_ci t_error("pthread_barrier_wait failed: got %d \"%s\", wanted either 0 or %d\n", 68570af302Sopenharmony_ci r, strerror(r), PTHREAD_BARRIER_SERIAL_THREAD); 69570af302Sopenharmony_ci TEST(r, pthread_barrier_destroy(&barrier2), ""); 70570af302Sopenharmony_ci TESTX(r, pthread_mutex_lock(&mtx), EOWNERDEAD, ""); 71570af302Sopenharmony_ci TEST(r, pthread_join(td, &res), ""); 72570af302Sopenharmony_ci TEST(r, pthread_mutex_consistent(&mtx), ""); 73570af302Sopenharmony_ci TEST(r, pthread_mutex_unlock(&mtx), ""); 74570af302Sopenharmony_ci TEST(r, pthread_mutex_destroy(&mtx), ""); 75570af302Sopenharmony_ci} 76570af302Sopenharmony_ci 77570af302Sopenharmony_ciint main(void) 78570af302Sopenharmony_ci{ 79570af302Sopenharmony_ci for (int pshared=0; pshared<=1; pshared++) 80570af302Sopenharmony_ci for (int pi=0; pi<=1; pi++) 81570af302Sopenharmony_ci f(pshared, pi); 82570af302Sopenharmony_ci return t_status; 83570af302Sopenharmony_ci} 84