Support futexes on FreeBSD

This commit is contained in:
Justine Tunney 2022-10-02 11:56:27 -07:00
parent 795d295590
commit 7549a5755e
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
10 changed files with 81 additions and 31 deletions

View file

@ -1,8 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_THREAD_FREEBSD_INTERNAL_H_
#define COSMOPOLITAN_LIBC_THREAD_FREEBSD_INTERNAL_H_
#include "libc/intrin/asmflag.h"
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/intrin/asmflag.h"
/**
* @fileoverview FreeBSD Threading
@ -11,9 +11,12 @@
* maximum legal range is PID_MAX + 2 (100001) through INT_MAX
*/
#define UMTX_OP_MUTEX_WAIT 17
#define UMTX_OP_MUTEX_WAKE 18
#define UMTX_ABSTIME 1
#define UMTX_OP_WAIT 2
#define UMTX_OP_WAIT_UINT 11
#define UMTX_OP_WAIT_UINT_PRIVATE 15
#define UMTX_OP_WAKE 3
#define UMTX_OP_WAKE_PRIVATE 16
#define UMTX_ABSTIME 1
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -42,7 +45,7 @@ struct _umtx_time {
uint32_t _clockid;
};
int _umtx_op(void *, int, unsigned long, void *, void *);
int sys_umtx_op(void *, int, unsigned long, void *, void *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -27,14 +27,14 @@
* Waits for condition with optional time limit, e.g.
*
* struct timespec ts; // one second timeout
* ts = _timespec_add(_timespec_mono(), _timespec_frommillis(1000));
* ts = _timespec_add(_timespec_real(), _timespec_frommillis(1000));
* if (pthread_cond_timedwait(cond, mutex, &ts) == ETIMEDOUT) {
* // handle timeout...
* }
*
* @param mutex needs to be held by thread when calling this function
* @param abstime may be null to wait indefinitely and should contain
* some arbitrary interval added to a `CLOCK_MONOTONIC` timestamp
* some arbitrary interval added to a `CLOCK_REALTIME` timestamp
* @return 0 on success, or errno on error
* @raise ETIMEDOUT if `abstime` was specified and the current time
* exceeded its value

View file

@ -29,6 +29,7 @@
#include "libc/nt/runtime.h"
#include "libc/nt/synchronization.h"
#include "libc/sysv/consts/futex.h"
#include "libc/thread/freebsd.internal.h"
#include "libc/thread/wait0.internal.h"
int _futex(atomic_int *, int, int, const struct timespec *);
@ -64,6 +65,8 @@ static void _wait0_futex(const atomic_int *a, int e) {
} else {
rc = -GetLastError();
}
} else if (IsFreebsd()) {
rc = sys_umtx_op(a, UMTX_OP_WAIT_UINT, 0, 0, 0);
} else {
rc = _futex(a, op, e, 0);
if (IsOpenbsd() && rc > 0) {