Add regress test for futexes in shared anonymous memory.
authorkettenis <kettenis@openbsd.org>
Mon, 22 Nov 2021 18:42:16 +0000 (18:42 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 22 Nov 2021 18:42:16 +0000 (18:42 +0000)
ok mpi@

regress/sys/kern/futex/futex.c

index 018e1c6..abaca82 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: futex.c,v 1.4 2021/06/11 10:30:36 kettenis Exp $ */
+/*     $OpenBSD: futex.c,v 1.5 2021/11/22 18:42:16 kettenis Exp $ */
 /*
  * Copyright (c) 2017 Martin Pieuchot
  *
@@ -124,6 +124,48 @@ main(int argc, char *argv[])
 
        assert(munmap(shlock, sizeof(*shlock)) == 0);
 
+       /* Create anonymous memory for sharing a lock. */
+       shlock = mmap(NULL, sizeof(*shlock), PROT_READ | PROT_WRITE,
+           MAP_ANON | MAP_SHARED, -1, 0);
+       assert(shlock != MAP_FAILED);
+
+       /* Wake another process. */
+       pid = fork();
+       assert(pid != -1);
+       if (pid == 0) {
+               usleep(50000);
+               futex_wake(shlock, -1, 0);
+               _exit(0);
+       } else {
+               assert(futex_twait(shlock, 0, 0, NULL, 0) == 0);
+               assert(waitpid(pid, &status, 0) == pid);
+               assert(WIFEXITED(status));
+               assert(WEXITSTATUS(status) == 0);
+       }
+
+       /* Cannot wake another process using a private futex. */
+       for (i = 1; i < 4; i++) {
+               pid = fork();
+               assert(pid != -1);
+               if (pid == 0) {
+                       usleep(50000);
+                       futex_wake(shlock, -1,
+                           (i & 1) ? FUTEX_PRIVATE_FLAG : 0);
+                       _exit(0);
+               } else {
+                       tmo.tv_sec = 0;
+                       tmo.tv_nsec = 200000000;
+                       assert(futex_twait(shlock, 0, CLOCK_REALTIME, &tmo,
+                           (i & 2) ? FUTEX_PRIVATE_FLAG : 0) == -1);
+                       assert(errno == ETIMEDOUT);
+                       assert(waitpid(pid, &status, 0) == pid);
+                       assert(WIFEXITED(status));
+                       assert(WEXITSTATUS(status) == 0);
+               }
+       }
+
+       assert(munmap(shlock, sizeof(*shlock)) == 0);
+
        return 0;
 }