From 45c5bf044a063a289fad6a53b8d27ce675d9c272 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sun, 10 Jul 2022 11:38:53 +0200 Subject: init/lib: implement "evil semaphores" I started implementing native semaphores in the kernel, but then I've realized that I can implement them in userland using pipes. Thus, this hot garbage was born. --- src/init/tests/main.c | 1 + src/init/tests/main.h | 1 + src/init/tests/pipe.c | 2 -- src/init/tests/semaphore.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/init/tests/semaphore.c (limited to 'src/init/tests') diff --git a/src/init/tests/main.c b/src/init/tests/main.c index f0845fe..9adb50c 100644 --- a/src/init/tests/main.c +++ b/src/init/tests/main.c @@ -146,5 +146,6 @@ void test_all(void) { run_forked(test_memflag); run_forked(test_malloc); run_forked(test_pipe); + run_forked(test_semaphore); run_forked(test_misc); } diff --git a/src/init/tests/main.h b/src/init/tests/main.h index 47c2507..ed11c5e 100644 --- a/src/init/tests/main.h +++ b/src/init/tests/main.h @@ -4,6 +4,7 @@ void stress_all(void); void test_all(void); void test_pipe(void); +void test_semaphore(void); #ifdef TEST_MACROS diff --git a/src/init/tests/pipe.c b/src/init/tests/pipe.c index a980cb8..8e9d243 100644 --- a/src/init/tests/pipe.c +++ b/src/init/tests/pipe.c @@ -113,6 +113,4 @@ void test_pipe(void) { // not a to.do detect when all processes that can read are stuck on writing to the pipe and vice versa // it seems like linux just lets the process hang endlessly. - - // TODO kill process that's waiting on a pipe } diff --git a/src/init/tests/semaphore.c b/src/init/tests/semaphore.c new file mode 100644 index 0000000..e542f0b --- /dev/null +++ b/src/init/tests/semaphore.c @@ -0,0 +1,70 @@ +#define TEST_MACROS +#include +#include +#include +#include +#include + +static void odd(struct evil_sem *sem1, struct evil_sem *sem2) { + printf("1"); + esem_signal(sem1); + + esem_wait(sem2); + printf("3"); + esem_signal(sem1); + + esem_wait(sem2); + printf("5"); + esem_signal(sem1); +} + +static void even(struct evil_sem *sem1, struct evil_sem *sem2) { + esem_wait(sem1); + printf("2"); + esem_signal(sem2); + + esem_wait(sem1); + printf("4"); + esem_signal(sem2); + + esem_wait(sem1); + printf("6"); + esem_signal(sem2); +} + +void test_semaphore(void) { + struct evil_sem *sem1, *sem2; + + // TODO pipe-based test + + sem1 = esem_new(0); + sem2 = esem_new(0); + assert(sem1 && sem2); + if (!_syscall_fork(0, NULL)) { + odd(sem1, sem2); + _syscall_exit(69); + } else { + even(sem1, sem2); + assert(_syscall_await() == 69); + } + esem_free(sem1); + esem_free(sem2); + + printf("\n"); + + sem1 = esem_new(0); + sem2 = esem_new(0); + assert(sem1 && sem2); + if (!_syscall_fork(0, NULL)) { + even(sem1, sem2); + _syscall_exit(69); + } else { + odd(sem1, sem2); + assert(_syscall_await() == 69); + _syscall_await(); + } + esem_free(sem1); + esem_free(sem2); + + printf("\n"); +} -- cgit v1.2.3