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