summaryrefslogtreecommitdiff
path: root/src/cmd/tests/libc/esemaphore.c
diff options
context:
space:
mode:
authordzwdz2023-08-14 18:51:07 +0200
committerdzwdz2023-08-14 18:51:07 +0200
commit642b5fb0007b64c77d186fcb018d571152ee1d47 (patch)
tree1c466461f3602d306be309a053edae558ef2568e /src/cmd/tests/libc/esemaphore.c
parent8050069c57b729c18c19b1a03ab6e4bf63b4735e (diff)
reorganization: first steps
Diffstat (limited to 'src/cmd/tests/libc/esemaphore.c')
-rw-r--r--src/cmd/tests/libc/esemaphore.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/cmd/tests/libc/esemaphore.c b/src/cmd/tests/libc/esemaphore.c
new file mode 100644
index 0000000..f089f4f
--- /dev/null
+++ b/src/cmd/tests/libc/esemaphore.c
@@ -0,0 +1,95 @@
+#include "../tests.h"
+#include <camellia/flags.h>
+#include <camellia/syscalls.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <esemaphore.h>
+
+static void odd(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) {
+ _sys_write(out, "1", 1, -1, 0);
+ esem_signal(sem1);
+
+ esem_wait(sem2);
+ _sys_write(out, "3", 1, -1, 0);
+ esem_signal(sem1);
+
+ esem_wait(sem2);
+ _sys_write(out, "5", 1, -1, 0);
+ esem_signal(sem1);
+}
+
+static void even(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) {
+ esem_wait(sem1);
+ _sys_write(out, "2", 1, -1, 0);
+ esem_signal(sem2);
+
+ esem_wait(sem1);
+ _sys_write(out, "4", 1, -1, 0);
+ esem_signal(sem2);
+
+ esem_wait(sem1);
+ _sys_write(out, "6", 1, -1, 0);
+ esem_signal(sem2);
+}
+
+static void test_semaphore(void) {
+ struct evil_sem *sem1, *sem2;
+ hid_t pipe[2];
+ test(_sys_pipe(pipe, 0) >= 0);
+
+ if (!fork()) {
+ sem1 = esem_new(0);
+ sem2 = esem_new(0);
+ test(sem1 && sem2);
+ if (!fork()) {
+ odd(pipe[1], sem1, sem2);
+ exit(69);
+ } else {
+ even(pipe[1], sem1, sem2);
+ test(_sys_await() == 69);
+ }
+ esem_free(sem1);
+ esem_free(sem2);
+
+ _sys_write(pipe[1], "|", 1, -1, 0);
+
+ sem1 = esem_new(0);
+ sem2 = esem_new(0);
+ test(sem1 && sem2);
+ if (!fork()) {
+ even(pipe[1], sem1, sem2);
+ exit(69);
+ } else {
+ odd(pipe[1], sem1, sem2);
+ test(_sys_await() == 69);
+ _sys_await();
+ }
+ esem_free(sem1);
+ esem_free(sem2);
+
+ _sys_filicide();
+ exit(0);
+ } else {
+ close(pipe[1]);
+
+ char buf[16];
+ size_t pos = 0;
+ for (;;) {
+ int ret = _sys_read(pipe[0], buf + pos, sizeof(buf) - pos, 0);
+ if (ret < 0) break;
+ pos += ret;
+ }
+ buf[pos] = '\0'; // idc about the "potential" overflow
+ if (strcmp(buf, "123456|123456")) {
+ printf("%s\n", buf);
+ test_fail();
+ }
+
+ _sys_await();
+ }
+}
+
+void r_libc_esemaphore(void) {
+ run_test(test_semaphore);
+}