|
1 |
| ---- src/mongo/platform/waitable_atomic.cpp.orig 2024-07-23 11:53:14 UTC |
| 1 | +--- src/mongo/platform/waitable_atomic.cpp.orig 2024-11-20 23:53:48 UTC |
2 | 2 | +++ src/mongo/platform/waitable_atomic.cpp
|
3 | 3 | @@ -34,6 +34,9 @@
|
4 | 4 | #ifdef __linux__
|
|
10 | 10 | #elif defined(_WIN32)
|
11 | 11 | #include <synchapi.h>
|
12 | 12 | #endif
|
13 |
| -@@ -228,6 +231,52 @@ bool waitUntil(const void* uaddr, |
14 |
| - } |
15 |
| - |
16 |
| - if (__ulock_wait(UL_COMPARE_AND_WAIT, const_cast<void*>(uaddr), old, timeoutMicros) != -1) |
17 |
| -+ return true; |
18 |
| -+ |
19 |
| -+ // There isn't a good list of possible errors, so assuming that anything other than a timeout |
20 |
| -+ // error is a possible spurious wakeup. |
21 |
| -+ return timeoutOverflow || errno != ETIMEDOUT; |
| 13 | +@@ -233,6 +236,45 @@ bool waitUntil(const void* uaddr, |
| 14 | + // There isn't a good list of possible errors, so assuming that anything other than a timeout |
| 15 | + // error is a possible spurious wakeup. |
| 16 | + return timeoutOverflow || errno != ETIMEDOUT; |
22 | 17 | +}
|
23 | 18 | +
|
24 | 19 | +#elif defined(__FreeBSD__)
|
25 | 20 | +
|
26 | 21 | +void notifyOne(const void* uaddr) {
|
27 |
| -+ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, 1, NULL, NULL); |
| 22 | ++ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, 1, NULL, NULL); |
28 | 23 | +}
|
29 | 24 | +
|
30 | 25 | +void notifyMany(const void* uaddr, int nToWake) {
|
31 |
| -+ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, nToWake, NULL, NULL); |
| 26 | ++ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, nToWake, NULL, NULL); |
32 | 27 | +}
|
33 | 28 | +
|
34 | 29 | +void notifyAll(const void* uaddr) {
|
35 |
| -+ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, INT_MAX, NULL, NULL); |
| 30 | ++ _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE_PRIVATE, INT_MAX, NULL, NULL); |
36 | 31 | +}
|
37 | 32 | +
|
38 | 33 | +bool waitUntil(const void* uaddr,
|
39 | 34 | + uint32_t old,
|
40 | 35 | + boost::optional<system_clock::time_point> deadline) {
|
41 |
| -+ struct timespec timeout; |
42 |
| -+ bool timeoutOverflow = false; |
| 36 | ++ struct _umtx_time umtx_deadline; |
| 37 | ++ void* uaddr2 = nullptr; |
| 38 | ++ |
43 | 39 | + if (deadline) {
|
44 |
| -+ int64_t micros = durationCount<Microseconds>(*deadline - system_clock::now()); |
45 |
| -+ if (micros <= 0) { |
46 |
| -+ return false; // Synthesize a timeout. |
47 |
| -+ } |
| 40 | ++ umtx_deadline._timeout.tv_sec = durationCount<Seconds>(deadline->time_since_epoch()); |
| 41 | ++ umtx_deadline._timeout.tv_nsec = durationCount<Nanoseconds>( |
| 42 | ++ deadline->time_since_epoch() - stdx::chrono::seconds(umtx_deadline._timeout.tv_sec)); |
| 43 | ++ umtx_deadline._flags = UMTX_ABSTIME; |
| 44 | ++ umtx_deadline._clockid = CLOCK_REALTIME_FAST; |
| 45 | ++ uaddr2 = &umtx_deadline; |
| 46 | ++ } |
48 | 47 | +
|
49 |
| -+ if (micros > int64_t(std::numeric_limits<uint32_t>::max())) { |
50 |
| -+ // 2**32 micros is a little over an hour. If this happens, we wait as long as we can, |
51 |
| -+ // then return as-if a spurious wakeup happened, rather than a timeout. This will cause |
52 |
| -+ // the caller to loop and we will compute a smaller time each pass, eventually reaching |
53 |
| -+ // a representable timeout. |
54 |
| -+ micros = std::numeric_limits<uint32_t>::max(); |
55 |
| -+ timeoutOverflow = true; |
| 48 | ++ int umtxOpRet; |
| 49 | ++ if ((umtxOpRet = _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAIT_UINT_PRIVATE, old, (void*)sizeof(struct _umtx_time), uaddr2)) != 0) { |
| 50 | ++ if (errno == ETIMEDOUT) { |
| 51 | ++ return false; |
56 | 52 | + }
|
57 |
| -+ |
58 |
| -+ timeout.tv_sec = micros / 1000; |
59 |
| -+ timeout.tv_nsec = (micros % 1000) * 1000; |
| 53 | ++ invariant(umtxOpRet == 0, errorMessage(lastSystemError())); |
60 | 54 | + }
|
61 |
| -+ |
62 |
| -+ if (_umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAIT, old, (void*)sizeof(struct timespec), &timeout) != -1) |
63 |
| - return true; |
| 55 | ++ return true; |
| 56 | + } |
64 | 57 |
|
65 |
| - // There isn't a good list of possible errors, so assuming that anything other than a timeout |
| 58 | + #else |
0 commit comments