From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/14365 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH] libc-test: PI mutex tests Date: Tue, 9 Jul 2019 14:33:13 -0400 Message-ID: <20190709183313.GP1506@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="ulDeV4rPMk/y39in" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="9047"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mutt/1.5.21 (2010-09-15) To: musl@lists.openwall.com Original-X-From: musl-return-14381-gllmg-musl=m.gmane.org@lists.openwall.com Tue Jul 09 20:33:33 2019 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.89) (envelope-from ) id 1hkuvh-0002Ax-7N for gllmg-musl@m.gmane.org; Tue, 09 Jul 2019 20:33:29 +0200 Original-Received: (qmail 1281 invoked by uid 550); 9 Jul 2019 18:33:26 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 1238 invoked from network); 9 Jul 2019 18:33:25 -0000 Content-Disposition: inline Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:14365 Archived-At: --ulDeV4rPMk/y39in Content-Type: text/plain; charset=us-ascii Content-Disposition: inline --ulDeV4rPMk/y39in Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-add-PI-mutex-tests.patch" >From ed2b7eca0016b5a35b5281e950e82fa2bb511099 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 9 Jul 2019 14:29:20 -0400 Subject: [PATCH] add PI mutex tests for robust mutex tests, the code was already setup to be run more than once with different attributes (pshared); I've added PI the same way. for the main mutex tests, it would take a major refactoring to test and report errors well for both the normal and PI cases, so I just duplicated the source file with PI hard-coded on. this could be improved later if desired. --- src/functional/pthread_mutex_pi.c | 168 ++++++++++++++++++++++++++++++ src/functional/pthread_robust.c | 16 +-- 2 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 src/functional/pthread_mutex_pi.c 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; +} diff --git a/src/functional/pthread_robust.c b/src/functional/pthread_robust.c index 087353b..44f846f 100644 --- a/src/functional/pthread_robust.c +++ b/src/functional/pthread_robust.c @@ -4,11 +4,9 @@ #include "test.h" #define TEST(r, f, m) ( \ - ((r) = (f)) == 0 || (t_error("%s failed: (pshared==%d) %s (" m ")\n", #f, pshared, strerror(r)), 0) ) + ((r) = (f)) == 0 || (t_error("%s failed: (pshared==%d, pi==%d) %s (" m ")\n", #f, pshared, pi, strerror(r)), 0) ) #define TESTX(r, f, x, m) ( \ - ((r) = (f)) == (x) || (t_error("%s failed: (pshared==%d) got %d \"%s\" want %d \"%s\" (" m ")\n", #f, pshared, r, strerror(r), x, strerror(x)), 0) ) - -static int pshared; + ((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) ) static void *start_lock(void *arg) { @@ -25,7 +23,7 @@ static void *start_wait(void *arg) return 0; } -void f(void) +void f(int pshared, int pi) { pthread_t td; int r; @@ -41,6 +39,8 @@ void f(void) TEST(r, pthread_mutexattr_setrobust(&mtx_a, PTHREAD_MUTEX_ROBUST), "setting robust attribute"); if (pshared) TEST(r, pthread_mutexattr_setpshared(&mtx_a, PTHREAD_PROCESS_SHARED), "setting pshared attribute"); + if (pi) + TEST(r, pthread_mutexattr_setprotocol(&mtx_a, PTHREAD_PRIO_INHERIT), "setting PI attribute"); TEST(r, pthread_mutex_init(&mtx, &mtx_a), "initializing robust mutex"); TEST(r, pthread_mutex_lock(&mtx), "locking robust mutex"); TEST(r, pthread_mutex_unlock(&mtx), "unlocking robust mutex"); @@ -76,8 +76,8 @@ void f(void) int main(void) { - f(); - pshared=1; - f(); + for (int pshared=0; pshared<=1; pshared++) + for (int pi=0; pi<=1; pi++) + f(pshared, pi); return t_status; } -- 2.21.0 --ulDeV4rPMk/y39in--