Here is a proper diff (both sys and libc into one).
diff --git lib/libc/Symbols.list lib/libc/Symbols.list
index f9aa62ab6e8..4fa37a835aa 100644
--- lib/libc/Symbols.list
+++ lib/libc/Symbols.list
@@ -86,7 +86,10 @@ _thread_sys_fstatat
_thread_sys_fstatfs
_thread_sys_fsync
_thread_sys_ftruncate
-_thread_sys_futex
+_thread_sys_ofutex
+_thread_sys_futex_wait
+_thread_sys_futex_wake
+_thread_sys_futex_requeue
_thread_sys_futimens
_thread_sys_futimes
_thread_sys_getdents
@@ -282,7 +285,10 @@ fstatat
fstatfs
fsync
ftruncate
-futex
+ofutex
+futex_wait
+futex_wake
+futex_requeue
futimens
futimes
getdents
@@ -1685,6 +1691,7 @@ _spinunlock
_thread_atfork
_thread_dofork
_thread_set_callbacks
+futex
pthread_atfork
pthread_cond_broadcast
pthread_cond_destroy
diff --git lib/libc/gen/sigwait.c lib/libc/gen/sigwait.c
index 0321066fc81..4f6b4511d3f 100644
--- lib/libc/gen/sigwait.c
+++ lib/libc/gen/sigwait.c
@@ -58,6 +58,7 @@ sigwaitinfo(const sigset_t *set, siginfo_t *info)
LEAVE_CANCEL_POINT(ret == -1);
return (ret);
}
+#endif
int
sigtimedwait(const sigset_t *set, siginfo_t *info,
@@ -72,4 +73,3 @@ sigtimedwait(const sigset_t *set, siginfo_t *info,
LEAVE_CANCEL_POINT(ret == -1);
return (ret);
}
-#endif
diff --git lib/libc/hidden/sys/futex.h lib/libc/hidden/sys/futex.h
index dab25396b59..cec5ec68455 100644
--- lib/libc/hidden/sys/futex.h
+++ lib/libc/hidden/sys/futex.h
@@ -20,6 +20,8 @@
#include_next <sys/futex.h>
-PROTO_NORMAL(futex);
+PROTO_NORMAL(futex_wait);
+PROTO_NORMAL(futex_wake);
+PROTO_NORMAL(futex_requeue);
#endif /* !_LIBC_SYS_FUTEX_H_ */
diff --git lib/libc/shlib_version lib/libc/shlib_version
index 06f98b01084..5fb0770494f 100644
--- lib/libc/shlib_version
+++ lib/libc/shlib_version
@@ -1,4 +1,4 @@
major=96
-minor=0
+minor=1
# note: If changes were made to include/thread_private.h or if system calls
# were added/changed then librthread/shlib_version must also be updated.
diff --git lib/libc/sys/Makefile.inc lib/libc/sys/Makefile.inc
index 34769576ced..e60c42267a9 100644
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -87,7 +87,7 @@ DASM= ${ASM:.o=.do}
# syscalls that CANNOT FAIL. They can return whatever value they want,
# they just never want to set errno.
ASM_NOERR=__get_tcb.o __set_tcb.o __threxit.o __thrsleep.o __thrwakeup.o \
- futex.o \
+ ofutex.o futex_wait futex_wake futex_requeue \
getdtablecount.o getegid.o geteuid.o getgid.o getlogin_r.o \
getpgrp.o getpid.o getppid.o getrtable.o getthrid.o getuid.o \
issetugid.o \
diff --git lib/libc/thread/rthread_mutex.c lib/libc/thread/rthread_mutex.c
index c9a490033b3..9b2ca8f8fc0 100644
--- lib/libc/thread/rthread_mutex.c
+++ lib/libc/thread/rthread_mutex.c
@@ -284,3 +284,10 @@ pthread_mutex_unlock(pthread_mutex_t *mutexp)
return (0);
}
DEF_STRONG(pthread_mutex_unlock);
+
+int
+futex(volatile uint32_t *f, int op, int val, const struct timespec *timeout,
uint32_t *g)
+{
+ return _futex(f, op, val, timeout, g);
+}
+DEF_STRONG(futex);
diff --git lib/libc/thread/synch.h lib/libc/thread/synch.h
index 788890add89..d0e3dad7353 100644
--- lib/libc/thread/synch.h
+++ lib/libc/thread/synch.h
@@ -19,10 +19,33 @@
#include <sys/time.h>
#include <sys/futex.h>
+static inline int
+_futex(volatile uint32_t *p, int op, int val, const struct timespec *timeout,
uint32_t *g)
+{
+ int flags = 0;
+
+ if (op & FUTEX_PRIVATE_FLAG)
+ flags |= FT_PRIVATE;
+
+ switch (op) {
+ case FUTEX_WAIT:
+ case FUTEX_WAIT_PRIVATE:
+ return futex_wait(p, val, timeout, flags);
+ case FUTEX_WAKE:
+ case FUTEX_WAKE_PRIVATE:
+ return futex_wake(p, val, flags);
+ case FUTEX_REQUEUE:
+ case FUTEX_REQUEUE_PRIVATE:
+ return futex_requeue(p, val, g, timeout, flags);
+ }
+
+ return ENOSYS;
+}
+
static inline int
_wake(volatile uint32_t *p, int n)
{
- return futex(p, FUTEX_WAKE_PRIVATE, n, NULL, NULL);
+ return _futex(p, FUTEX_WAKE_PRIVATE, n, NULL, NULL);
}
static inline int
@@ -31,7 +54,7 @@ _twait(volatile uint32_t *p, int val, clockid_t clockid,
const struct timespec *
struct timespec rel;
if (abs == NULL)
- return futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL);
+ return _futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL);
if (abs->tv_nsec >= 1000000000 || clock_gettime(clockid, &rel))
return (EINVAL);
@@ -44,11 +67,11 @@ _twait(volatile uint32_t *p, int val, clockid_t clockid,
const struct timespec *
if (rel.tv_sec < 0)
return (ETIMEDOUT);
- return futex(p, FUTEX_WAIT_PRIVATE, val, &rel, NULL);
+ return _futex(p, FUTEX_WAIT_PRIVATE, val, &rel, NULL);
}
static inline int
_requeue(volatile uint32_t *p, int n, int m, volatile uint32_t *q)
{
- return futex(p, FUTEX_REQUEUE_PRIVATE, n, (void *)(long)m, q);
+ return _futex(p, FUTEX_REQUEUE_PRIVATE, n, (void *)(long)m, q);
}
diff --git sys/kern/init_sysent.c sys/kern/init_sysent.c
index cd7a726b1dc..8e64c28c301 100644
--- sys/kern/init_sysent.c
+++ sys/kern/init_sysent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_sysent.c,v 1.218 2020/03/18 19:35:00 anton Exp $ */
+/* $OpenBSD$ */
/*
* System call switch table.
@@ -198,8 +198,8 @@ struct sysent sysent[] = {
sys_getpgrp }, /* 81 = getpgrp */
{ 2, s(struct sys_setpgid_args), 0,
sys_setpgid }, /* 82 = setpgid */
- { 5, s(struct sys_futex_args), SY_NOLOCK | 0,
- sys_futex }, /* 83 = futex */
+ { 5, s(struct sys_ofutex_args), SY_NOLOCK | 0,
+ sys_ofutex }, /* 83 = ofutex */
{ 4, s(struct sys_utimensat_args), 0,
sys_utimensat }, /* 84 = utimensat */
{ 2, s(struct sys_futimens_args), 0,
@@ -751,5 +751,11 @@ struct sysent sysent[] = {
sys___set_tcb }, /* 329 = __set_tcb */
{ 0, 0, SY_NOLOCK | 0,
sys___get_tcb }, /* 330 = __get_tcb */
+ { 4, s(struct sys_futex_wait_args), SY_NOLOCK | 0,
+ sys_futex_wait }, /* 331 = futex_wait */
+ { 3, s(struct sys_futex_wake_args), SY_NOLOCK | 0,
+ sys_futex_wake }, /* 332 = futex_wake */
+ { 5, s(struct sys_futex_requeue_args), SY_NOLOCK | 0,
+ sys_futex_requeue }, /* 333 = futex_requeue */
};
diff --git sys/kern/kern_pledge.c sys/kern/kern_pledge.c
index 7bcc7636d99..7840f8487fc 100644
--- sys/kern/kern_pledge.c
+++ sys/kern/kern_pledge.c
@@ -266,7 +266,10 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = {
*/
[SYS___tfork] = PLEDGE_STDIO,
[SYS_sched_yield] = PLEDGE_STDIO,
- [SYS_futex] = PLEDGE_STDIO,
+ [SYS_ofutex] = PLEDGE_STDIO,
+ [SYS_futex_wait] = PLEDGE_STDIO,
+ [SYS_futex_wake] = PLEDGE_STDIO,
+ [SYS_futex_requeue] = PLEDGE_STDIO,
[SYS___thrsleep] = PLEDGE_STDIO,
[SYS___thrwakeup] = PLEDGE_STDIO,
[SYS___threxit] = PLEDGE_STDIO,
diff --git sys/kern/sys_futex.c sys/kern/sys_futex.c
index 140bb2b773e..04043c59e72 100644
--- sys/kern/sys_futex.c
+++ sys/kern/sys_futex.c
@@ -83,9 +83,74 @@ futex_init(void)
}
int
-sys_futex(struct proc *p, void *v, register_t *retval)
+sys_futex_wait(struct proc *p, void *v, register_t *retval)
{
- struct sys_futex_args /* {
+ struct sys_futex_wait_args /* {
+ syscallarg(uint32_t *) f;
+ syscallarg(inr) val;
+ syscallarg(const struct timespec *) timeout;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ uint32_t *uaddr = SCARG(uap, f);
+ uint32_t val = SCARG(uap, val);
+ const struct timespec *timeout = SCARG(uap, timeout);
+ int flags = SCARG(uap, flags);
+
+ KERNEL_LOCK();
+ rw_enter_write(&ftlock);
+ *retval = futex_wait(uaddr, val, timeout, flags);
+ rw_exit_write(&ftlock);
+ KERNEL_UNLOCK();
+
+ return 0;
+}
+
+int
+sys_futex_wake(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_futex_wake_args /* {
+ syscallarg(uint32_t *) f;
+ syscallarg(int) val;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ uint32_t *uaddr = SCARG(uap, f);
+ uint32_t val = SCARG(uap, val);
+ int flags = SCARG(uap, flags);
+
+ rw_enter_write(&ftlock);
+ *retval = futex_wake(uaddr, val, flags);
+ rw_exit_write(&ftlock);
+
+ return 0;
+}
+
+int
+sys_futex_requeue(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_futex_requeue_args /* {
+ syscallarg(uint32_t *) f;
+ syscallarg(int) val;
+ syscallarg(uint32_t *) g;
+ syscallarg(const struct timespec *) timeout;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ uint32_t *uaddr = SCARG(uap, f);
+ uint32_t val = SCARG(uap, val);
+ const struct timespec *timeout = SCARG(uap, timeout);
+ void *g = SCARG(uap, g);
+ int flags = SCARG(uap, flags);
+
+ rw_enter_write(&ftlock);
+ *retval = futex_requeue(uaddr, val, g, (u_long)timeout, flags);
+ rw_exit_write(&ftlock);
+
+ return 0;
+}
+
+int
+sys_ofutex(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_ofutex_args /* {
syscallarg(uint32_t *) f;
syscallarg(int) op;
syscallarg(inr) val;
diff --git sys/kern/syscalls.c sys/kern/syscalls.c
index 93058f5cc1c..3821676d6cb 100644
--- sys/kern/syscalls.c
+++ sys/kern/syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscalls.c,v 1.217 2020/03/18 19:35:00 anton Exp $ */
+/* $OpenBSD$ */
/*
* System call names.
@@ -103,7 +103,7 @@ char *syscallnames[] = {
"setgroups", /* 80 = setgroups */
"getpgrp", /* 81 = getpgrp */
"setpgid", /* 82 = setpgid */
- "futex", /* 83 = futex */
+ "ofutex", /* 83 = ofutex */
"utimensat", /* 84 = utimensat */
"futimens", /* 85 = futimens */
"kbind", /* 86 = kbind */
@@ -393,4 +393,7 @@ char *syscallnames[] = {
"#328 (obsolete __tfork51)", /* 328 = obsolete __tfork51 */
"__set_tcb", /* 329 = __set_tcb */
"__get_tcb", /* 330 = __get_tcb */
+ "futex_wait", /* 331 = futex_wait */
+ "futex_wake", /* 332 = futex_wake */
+ "futex_requeue", /* 333 = futex_requeue */
};
diff --git sys/kern/syscalls.master sys/kern/syscalls.master
index fb9f1a41c9b..ffef41db774 100644
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -186,7 +186,7 @@
const gid_t *gidset); }
81 STD { int sys_getpgrp(void); }
82 STD { int sys_setpgid(pid_t pid, pid_t pgid); }
-83 STD NOLOCK { int sys_futex(uint32_t *f, int op, int val, \
+83 STD NOLOCK { int sys_ofutex(uint32_t *f, int op, int val, \
const struct timespec *timeout, uint32_t *g); }
84 STD { int sys_utimensat(int fd, const char *path, \
const struct timespec *times, int flag); }
@@ -566,3 +566,9 @@
328 OBSOL __tfork51
329 STD NOLOCK { void sys___set_tcb(void *tcb); }
330 STD NOLOCK { void *sys___get_tcb(void); }
+331 STD NOLOCK { int sys_futex_wait(uint32_t *f, int val, \
+ const struct timespec *timeout, int flags); }
+332 STD NOLOCK { int sys_futex_wake(uint32_t *f, int val, int flags); }
+333 STD NOLOCK { int sys_futex_requeue(uint32_t *f, int val, \
+ uint32_t *g, const struct timespec *timeout, \
+ int flags); }
diff --git sys/sys/futex.h sys/sys/futex.h
index 62e32c977da..e6d350c1c15 100644
--- sys/sys/futex.h
+++ sys/sys/futex.h
@@ -23,11 +23,19 @@
#include <sys/cdefs.h>
__BEGIN_DECLS
-int futex(volatile uint32_t *, int, int, const struct timespec *,
- volatile uint32_t *);
+/* int futex(volatile uint32_t *, int, int, const struct timespec *,
+ volatile uint32_t *); */
+int futex_wait(uint32_t *f, int val, const struct timespec *timeout,
+ int flags);
+int futex_wake(uint32_t *f, int val, int flags);
+int futex_requeue(uint32_t *f, int val, uint32_t *g,
+ const struct timespec *timeout, int flags);
__END_DECLS
+
#endif /* ! _KERNEL */
+#define FT_PRIVATE 0x2 /* Futex is process-private. */
+
#define FUTEX_WAIT 1
#define FUTEX_WAKE 2
#define FUTEX_REQUEUE 3
diff --git sys/sys/syscall.h sys/sys/syscall.h
index 3500f7f3008..263cb582063 100644
--- sys/sys/syscall.h
+++ sys/sys/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.215 2020/03/18 19:35:00 anton Exp $ */
+/* $OpenBSD$ */
/*
* System call numbers.
@@ -251,8 +251,8 @@
/* syscall: "setpgid" ret: "int" args: "pid_t" "pid_t" */
#define SYS_setpgid 82
-/* syscall: "futex" ret: "int" args: "uint32_t *" "int" "int" "const struct
timespec *" "uint32_t *" */
-#define SYS_futex 83
+/* syscall: "ofutex" ret: "int" args: "uint32_t *" "int" "int" "const struct
timespec *" "uint32_t *" */
+#define SYS_ofutex 83
/* syscall: "utimensat" ret: "int" args: "int" "const char *" "const struct
timespec *" "int" */
#define SYS_utimensat 84
@@ -705,4 +705,13 @@
/* syscall: "__get_tcb" ret: "void *" args: */
#define SYS___get_tcb 330
-#define SYS_MAXSYSCALL 331
+/* syscall: "futex_wait" ret: "int" args: "uint32_t *" "int" "const struct
timespec *" "int" */
+#define SYS_futex_wait 331
+
+/* syscall: "futex_wake" ret: "int" args: "uint32_t *" "int" "int" */
+#define SYS_futex_wake 332
+
+/* syscall: "futex_requeue" ret: "int" args: "uint32_t *" "int" "uint32_t *"
"const struct timespec *" "int" */
+#define SYS_futex_requeue 333
+
+#define SYS_MAXSYSCALL 334
diff --git sys/sys/syscallargs.h sys/sys/syscallargs.h
index 22096060880..f03b7c85b2d 100644
--- sys/sys/syscallargs.h
+++ sys/sys/syscallargs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscallargs.h,v 1.218 2020/03/18 19:35:00 anton Exp $ */
+/* $OpenBSD$ */
/*
* System call argument lists.
@@ -390,7 +390,7 @@ struct sys_setpgid_args {
syscallarg(pid_t) pgid;
};
-struct sys_futex_args {
+struct sys_ofutex_args {
syscallarg(uint32_t *) f;
syscallarg(int) op;
syscallarg(int) val;
@@ -1109,6 +1109,27 @@ struct sys___set_tcb_args {
syscallarg(void *) tcb;
};
+struct sys_futex_wait_args {
+ syscallarg(uint32_t *) f;
+ syscallarg(int) val;
+ syscallarg(const struct timespec *) timeout;
+ syscallarg(int) flags;
+};
+
+struct sys_futex_wake_args {
+ syscallarg(uint32_t *) f;
+ syscallarg(int) val;
+ syscallarg(int) flags;
+};
+
+struct sys_futex_requeue_args {
+ syscallarg(uint32_t *) f;
+ syscallarg(int) val;
+ syscallarg(uint32_t *) g;
+ syscallarg(const struct timespec *) timeout;
+ syscallarg(int) flags;
+};
+
/*
* System call prototypes.
*/
@@ -1202,7 +1223,7 @@ int sys_getgroups(struct proc *, void *, register_t
*);
int sys_setgroups(struct proc *, void *, register_t *);
int sys_getpgrp(struct proc *, void *, register_t *);
int sys_setpgid(struct proc *, void *, register_t *);
-int sys_futex(struct proc *, void *, register_t *);
+int sys_ofutex(struct proc *, void *, register_t *);
int sys_utimensat(struct proc *, void *, register_t *);
int sys_futimens(struct proc *, void *, register_t *);
int sys_kbind(struct proc *, void *, register_t *);
@@ -1360,3 +1381,6 @@ int sys_symlinkat(struct proc *, void *, register_t
*);
int sys_unlinkat(struct proc *, void *, register_t *);
int sys___set_tcb(struct proc *, void *, register_t *);
int sys___get_tcb(struct proc *, void *, register_t *);
+int sys_futex_wait(struct proc *, void *, register_t *);
+int sys_futex_wake(struct proc *, void *, register_t *);
+int sys_futex_requeue(struct proc *, void *, register_t *);