mailing list of musl libc
 help / color / mirror / code / Atom feed
* [PATCH] libc-test: PI mutex tests
@ 2019-07-09 18:33 Rich Felker
  2019-07-09 21:13 ` Szabolcs Nagy
  0 siblings, 1 reply; 2+ messages in thread
From: Rich Felker @ 2019-07-09 18:33 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: 0001-add-PI-mutex-tests.patch --]
[-- Type: text/plain, Size: 7292 bytes --]

From ed2b7eca0016b5a35b5281e950e82fa2bb511099 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
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 <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] libc-test: PI mutex tests
  2019-07-09 18:33 [PATCH] libc-test: PI mutex tests Rich Felker
@ 2019-07-09 21:13 ` Szabolcs Nagy
  0 siblings, 0 replies; 2+ messages in thread
From: Szabolcs Nagy @ 2019-07-09 21:13 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2019-07-09 14:33:13 -0400]:
> >From ed2b7eca0016b5a35b5281e950e82fa2bb511099 Mon Sep 17 00:00:00 2001
> From: Rich Felker <dalias@aerifal.cx>
> 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.

applied.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-07-09 21:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-09 18:33 [PATCH] libc-test: PI mutex tests Rich Felker
2019-07-09 21:13 ` Szabolcs Nagy

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).