Re: advice for implementing an atomics wrapper

From: Ronald Klop <ronald-lists_at_klop.ws>
Date: Tue, 23 Jul 2024 16:09:11 UTC
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.
>>>  
>> 
>>  
>