Date: Tue, 23 Jul 2024 18:09:11 +0200 (CEST) From: Ronald Klop <ronald-lists@klop.ws> To: freebsd-ports@freebsd.org Cc: Michael Gmelin <grembo@freebsd.org> Subject: Re: advice for implementing an atomics wrapper Message-ID: <649335513.7189.1721750951946@localhost> In-Reply-To: <E0DA696F-F74E-4E93-B34F-3646169C3DBC@freebsd.org> References: <1711627700.7093.1721744204825@localhost> <E0DA696F-F74E-4E93-B34F-3646169C3DBC@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_7188_792930881.1721750951921 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hi, The __APPLE__ implementation also pointed to the implementation in that file and I used it to come up with a patch. #elif defined(__FreeBSD__) void notifyOne(const void* uaddr) { _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, 1, NULL, NULL); } void notifyMany(const void* uaddr, int nToWake) { _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, nToWake, NULL, NULL); } void notifyAll(const void* uaddr) { _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, INT_MAX, NULL, NULL); } bool waitUntil(const void* uaddr, uint32_t old, boost::optional<system_clock::time_point> deadline) { struct timespec timeout; bool timeoutOverflow = false; if (deadline) { int64_t micros = durationCount<Microseconds>(*deadline - system_clock::now()); if (micros <= 0) { return false; // Synthesize a timeout. } if (micros > int64_t(std::numeric_limits<uint32_t>::max())) { // 2**32 micros is a little over an hour. If this happens, we wait as long as we can, // then return as-if a spurious wakeup happened, rather than a timeout. This will cause // the caller to loop and we will compute a smaller time each pass, eventually reaching // a representable timeout. micros = std::numeric_limits<uint32_t>::max(); timeoutOverflow = true; } timeout.tv_sec = micros / 1000; timeout.tv_nsec = (micros % 1000) * 1000; } if (_umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAIT, old, (void*)sizeof(struct timespec), &timeout) != -1) return true; // There isn't a good list of possible errors, so assuming that anything other than a timeout // error is a possible spurious wakeup. return timeoutOverflow || errno != ETIMEDOUT; } It compiles and runs in my simple tests (although I don't know if my simple tests execute this part of mongodb code). Suggestions are of course welcome. Regards, Ronald. Van: Michael Gmelin <grembo@freebsd.org> Datum: dinsdag, 23 juli 2024 17:32 Aan: Ronald Klop <ronald-lists@klop.ws> Onderwerp: Re: advice for implementing an atomics wrapper > > > Does this help? > > https://reviews.llvm.org/D142134 > > >> On 23. Jul 2024, at 16:17, Ronald Klop <ronald-lists@klop.ws> wrote: >> > >> >> Sorry, >> >> Something broke the pasted URL. >> https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp >> >> Another attempt. >> >> Ronald. >> >> Van: Ronald Klop <ronald-lists@klop.ws> >> Datum: dinsdag, 23 juli 2024 16:14 >> Aan: freebsd-ports@freebsd.org >> Onderwerp: advice for implementing an atomics wrapper >>> >>> Hi, >>> >>> For mongodb 8.0 I need to give a FreeBSD implementation of this file. >>> >>> https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp >>> >>> Using the __Apple__ definition gives: >>> ld.lld: error: undefined symbol: __ulock_wake >>> ld.lld: error: undefined symbol: __ulock_wait >>> >>> And the __linux__ definition uses futex which FreeBSD does not have AFAIK. >>> >>> What is an easy way to port this file? >>> >>> Regards, >>> Ronald. >>> >> >> > ------=_Part_7188_792930881.1721750951921 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit <html><head></head><body>Hi,<br> <br> The __APPLE__ implementation also pointed to the implementation in that file and I used it to come up with a patch.<br> <br> #elif defined(__FreeBSD__)<br> <br> void notifyOne(const void* uaddr) {<br> _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, 1, NULL, NULL);<br> }<br> <br> void notifyMany(const void* uaddr, int nToWake) {<br> _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, nToWake, NULL, NULL);<br> }<br> <br> void notifyAll(const void* uaddr) {<br> _umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAKE, INT_MAX, NULL, NULL);<br> }<br> <br> bool waitUntil(const void* uaddr,<br> uint32_t old,<br> boost::optional<system_clock::time_point> deadline) {<br> struct timespec timeout;<br> bool timeoutOverflow = false;<br> if (deadline) {<br> int64_t micros = durationCount<Microseconds>(*deadline - system_clock::now());<br> if (micros <= 0) {<br> return false; // Synthesize a timeout.<br> }<br> <br> if (micros > int64_t(std::numeric_limits<uint32_t>::max())) {<br> // 2**32 micros is a little over an hour. If this happens, we wait as long as we can,<br> // then return as-if a spurious wakeup happened, rather than a timeout. This will cause<br> // the caller to loop and we will compute a smaller time each pass, eventually reaching<br> // a representable timeout.<br> micros = std::numeric_limits<uint32_t>::max();<br> timeoutOverflow = true;<br> }<br> <br> timeout.tv_sec = micros / 1000;<br> timeout.tv_nsec = (micros % 1000) * 1000;<br> }<br> <br> if (_umtx_op(const_cast<void*>(uaddr), UMTX_OP_WAIT, old, (void*)sizeof(struct timespec), &timeout) != -1)<br> return true;<br> <br> // There isn't a good list of possible errors, so assuming that anything other than a timeout<br> // error is a possible spurious wakeup.<br> return timeoutOverflow || errno != ETIMEDOUT;<br> }<br> <br> <br> It compiles and runs in my simple tests (although I don't know if my simple tests execute this part of mongodb code). Suggestions are of course welcome.<br> <br> Regards,<br> Ronald.<br> <br> <p><strong>Van:</strong> Michael Gmelin <grembo@freebsd.org><br> <strong>Datum:</strong> dinsdag, 23 juli 2024 17:32<br> <strong>Aan:</strong> Ronald Klop <ronald-lists@klop.ws><br> <strong>Onderwerp:</strong> Re: advice for implementing an atomics wrapper</p> <blockquote style="padding-right: 0px; padding-left: 5px; margin-left: 5px; border-left: #000000 2px solid; margin-right: 0px"> <div class="MessageRFC822Viewer" id="P"> <div class="MultipartAlternativeViewer"> <div class="TextHTMLViewer" id="P.P.P"> <div> </div> <div>Does this help?</div> <div> </div> <div><a href="https://reviews.llvm.org/D142134">https://reviews.llvm.org/D142134</a></div> <div> <div> </div> <blockquote>On 23. Jul 2024, at 16:17, Ronald Klop <ronald-lists@klop.ws> wrote:<br> </blockquote> </div> <blockquote> <div>Sorry,<br> <br> Something broke the pasted URL.<br> <a href="https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp">https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp</a><br> <br> Another attempt.<br> <br> Ronald.<br> <p><strong>Van:</strong> Ronald Klop <ronald-lists@klop.ws><br> <strong>Datum:</strong> dinsdag, 23 juli 2024 16:14<br> <strong>Aan:</strong> freebsd-ports@freebsd.org<br> <strong>Onderwerp:</strong> advice for implementing an atomics wrapper</p> <blockquote style="padding-right: 0px; padding-left: 5px; margin-left: 5px; border-left: #000000 2px solid; margin-right: 0px"> <div class="MessageRFC822Viewer" id="P"> <div class="MultipartAlternativeViewer"> <div class="TextHTMLViewer" id="P.P.P">Hi,<br> <br> For mongodb 8.0 I need to give a FreeBSD implementation of this file.<br> <br> <a href="https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp">https://github.com/mongodb/mongo/blob/master/src/mongo/platform/waitable_atomic.cpp</a><br> <br> Using the __Apple__ definition gives:<br> ld.lld: error: undefined symbol: __ulock_wake<br> ld.lld: error: undefined symbol: __ulock_wait<br> <br> And the __linux__ definition uses futex which FreeBSD does not have AFAIK.<br> <br> What is an easy way to port this file?<br> <br> Regards,<br> Ronald.<br> </div> </div> </div> </blockquote> <br> </div> </blockquote> </div> </div> </div> </blockquote> <br> </body></html> ------=_Part_7188_792930881.1721750951921--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?649335513.7189.1721750951946>