1 # Original upstream implementation:
2 #   https://jira.mongodb.org/browse/SERVER-81797
3 # Attempt to upstream this patch:
4 #   https://github.com/mongodb/mongo/pull/1607
5 #   https://jira.mongodb.org/browse/SERVER-99225
6 #
7 --- src/mongo/platform/waitable_atomic.cpp.orig	2024-11-20 23:53:48 UTC
8 +++ src/mongo/platform/waitable_atomic.cpp
9 @@ -34,6 +34,9 @@
10  #ifdef __linux__
11  #include <linux/futex.h>
12  #include <sys/syscall.h>
13 +#elif defined(__FreeBSD__)
14 +#include <sys/types.h>
15 +#include <sys/umtx.h>
16  #elif defined(_WIN32)
17  #include <synchapi.h>
18  #endif
19 @@ -233,6 +236,45 @@ bool waitUntil(const void* uaddr,
20      // There isn't a good list of possible errors, so assuming that anything other than a timeout
21      // error is a possible spurious wakeup.
22      return timeoutOverflow || errno != ETIMEDOUT;
23 +}
24 +
25 +#elif defined(__FreeBSD__)
26 +
27 +void notifyOne(const void* uaddr) {
28 +    _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, 1, NULL, NULL);
29 +}
30 +
31 +void notifyMany(const void* uaddr, int nToWake) {
32 +    _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, nToWake, NULL, NULL);
33 +}
34 +
35 +void notifyAll(const void* uaddr) {
36 +    _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, INT_MAX, NULL, NULL);
37 +}
38 +
39 +bool waitUntil(const void* uaddr,
40 +               uint32_t old,
41 +               boost::optional<system_clock::time_point> deadline) {
42 +    struct _umtx_time umtx_deadline;
43 +    void* uaddr2 = nullptr;
44 +
45 +    if (deadline) {
46 +        umtx_deadline._timeout.tv_sec = durationCount<Seconds>(deadline->time_since_epoch());
47 +        umtx_deadline._timeout.tv_nsec = durationCount<Nanoseconds>(
48 +                deadline->time_since_epoch() - stdx::chrono::seconds(umtx_deadline._timeout.tv_sec));
49 +        umtx_deadline._flags = UMTX_ABSTIME;
50 +        umtx_deadline._clockid = CLOCK_REALTIME_FAST;
51 +        uaddr2 = &umtx_deadline;
52 +    }
53 +
54 +    int umtxOpRet;
55 +    if ((umtxOpRet = _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAIT_UINT_PRIVATE, old, (void*)sizeof(struct _umtx_time), uaddr2)) == -1) {
56 +        if (errno == ETIMEDOUT) {
57 +            return false;
58 +        }
59 +        invariant(umtxOpRet == 0, errorMessage(lastSystemError()));
60 +    }
61 +    return true;
62  }
63 
64  #else
65