• A spinlock contention profiler

    From Mr Flibble@flibble@red-dwarf.jmc.corp to comp.lang.c++ on Sun Dec 21 21:40:59 2025
    From Newsgroup: comp.lang.c++

    Hi!

    In neolib (C++ support library used by neoGFX) you can now profile
    spinlock mutex contention:

    struct i_mutex_profiler : i_service
    {
    template <typename ProfilerTag>
    friend class recursive_spinlock;
    public:
    virtual bool enabled(std::chrono::microseconds& aTimeout, std::uint32_t& aMaxCount, bool& aEnhancedMetrics) const noexcept = 0;
    virtual void enable(std::chrono::microseconds aTimeout = std::chrono::microseconds{ 100 }, std::uint32_t aMaxCount = 10u, bool aEnhancedMetrics = false) = 0;
    virtual void disable() noexcept = 0;
    public:
    virtual void subscribe(i_mutex_profiler_observer& aObserver) = 0;
    virtual void unsubscribe(i_mutex_profiler_observer& aObserver) = 0;
    private:
    virtual void notify_contention(i_lockable& aMutex, const std::chrono::microseconds& aContendedFor, mutex_lock_info const* aPreviousLocks, std::size_t aPreviousLocksCount) noexcept = 0;
    public:
    static uuid const& iid() { static uuid const sIid{ 0xc1546ec1,
    0x9cfb, 0x4fe7, 0xb93e, { 0x1, 0xc1, 0x2a, 0x5f, 0xf1, 0x62 } }; return
    sIid; }
    };

    static struct debug_mutexes : neolib::i_mutex_profiler_observer
    {
    void mutex_contended(neolib::i_lockable& aMutex, const std::chrono::microseconds& aContendedFor,
    neolib::mutex_lock_info const* aPreviousLocks, std::size_t aPreviousLocksCount) noexcept final
    {
    }
    } sDebugMutexes;

    service<neolib::i_mutex_profiler>().enable(std::chrono::microseconds{ 100 }, 10u, true);
    service<neolib::i_mutex_profiler>().subscribe(sDebugMutexes);

    /Flibble
    --
    meet ever shorter deadlines, known as "beat the clock"
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Mon Dec 22 03:31:27 2025
    From Newsgroup: comp.lang.c++

    Pure spinlocks don't make sense in userspace.

    Am 21.12.2025 um 22:40 schrieb Mr Flibble:
    Hi!

    In neolib (C++ support library used by neoGFX) you can now profile
    spinlock mutex contention:

    struct i_mutex_profiler : i_service
    {
    template <typename ProfilerTag>
    friend class recursive_spinlock;
    public:
    virtual bool enabled(std::chrono::microseconds& aTimeout, std::uint32_t& aMaxCount, bool& aEnhancedMetrics) const noexcept = 0;
    virtual void enable(std::chrono::microseconds aTimeout = std::chrono::microseconds{ 100 }, std::uint32_t aMaxCount = 10u, bool aEnhancedMetrics = false) = 0;
    virtual void disable() noexcept = 0;
    public:
    virtual void subscribe(i_mutex_profiler_observer& aObserver) = 0;
    virtual void unsubscribe(i_mutex_profiler_observer& aObserver) = 0;
    private:
    virtual void notify_contention(i_lockable& aMutex, const std::chrono::microseconds& aContendedFor, mutex_lock_info const* aPreviousLocks, std::size_t aPreviousLocksCount) noexcept = 0;
    public:
    static uuid const& iid() { static uuid const sIid{ 0xc1546ec1, 0x9cfb, 0x4fe7, 0xb93e, { 0x1, 0xc1, 0x2a, 0x5f, 0xf1, 0x62 } }; return
    sIid; }
    };

    static struct debug_mutexes : neolib::i_mutex_profiler_observer
    {
    void mutex_contended(neolib::i_lockable& aMutex, const std::chrono::microseconds& aContendedFor,
    neolib::mutex_lock_info const* aPreviousLocks, std::size_t aPreviousLocksCount) noexcept final
    {
    }
    } sDebugMutexes;

    service<neolib::i_mutex_profiler>().enable(std::chrono::microseconds{ 100 }, 10u, true);
    service<neolib::i_mutex_profiler>().subscribe(sDebugMutexes);

    /Flibble


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mr Flibble@flibble@red-dwarf.jmc.corp to comp.lang.c++ on Mon Dec 22 21:45:11 2025
    From Newsgroup: comp.lang.c++

    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks? You know what they say
    about assumptions...

    /Flibble
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Mon Dec 22 13:52:29 2025
    From Newsgroup: comp.lang.c++

    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks? You know what they say about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while trying
    to avoid a slow path call into a kernel wait.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Mon Dec 22 13:54:14 2025
    From Newsgroup: comp.lang.c++

    On 12/22/2025 1:52 PM, Chris M. Thomasson wrote:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what they say
    about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while trying
    to avoid a slow path call into a kernel wait.

    If a mutex API has a try_lock() function, then it can be morphed into an adaptive mutex without even altering its private logic.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Fri Dec 26 22:11:43 2025
    From Newsgroup: comp.lang.c++

    Am 22.12.2025 um 22:52 schrieb Chris M. Thomasson:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what they say
    about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while
    trying to avoid a slow path call into a kernel wait.

    These adaptive mutexes rarely prove effective. First, the competing threads only need to hold the mutex for a very short time for the spinning to have
    any chance of success.Second, the mutex must be locked and released
    frequently
    so that locking attempts and locking situations often overlap. Both of these conditions don't occur often.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Fri Dec 26 15:06:37 2025
    From Newsgroup: comp.lang.c++

    On 12/26/2025 1:11 PM, Bonita Montero wrote:
    Am 22.12.2025 um 22:52 schrieb Chris M. Thomasson:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what they say >>> about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while
    trying to avoid a slow path call into a kernel wait.

    These adaptive mutexes rarely prove effective. First, the competing threads only need to hold the mutex for a very short time for the spinning to have any chance of success.Second, the mutex must be locked and released frequently
    so that locking attempts and locking situations often overlap. Both of
    these
    conditions don't occur often.


    Lets take an adaptive mutex with a spin count threshold at 1. So, how
    many spins avoided a kernel wait on the mutex object? I created a
    different kind of mutex where a try_lock failure is an opportunity for
    the thread try to do other work. The api for this try work is prefixed
    with try_*. ;^)

    A failed try_lock() is not a reason to burn cycles with PAUSE.
    ItrCOs a signal that someone else is making progress, so yourCOre free to redirect your energy.

    That is why a failed try_lock can be very useful.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Fri Dec 26 15:21:05 2025
    From Newsgroup: comp.lang.c++

    A fun algo:


    void
    ct_lock_with_work_budget(
    ct_mutex& m,
    ct_work& ctx
    ) {
    int budget = INITIAL_WORK_BUDGET;

    for (;;) {
    if (m.try_lock()) {
    return;
    }

    if (budget <= 0) {
    m.lock_slow_path();
    return;
    }

    if (! ctx.try_do_something_useful()) {
    m.lock_slow_path();
    return;
    }

    --budget;
    }
    }
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Sat Dec 27 14:48:24 2025
    From Newsgroup: comp.lang.c++

    Am 22.12.2025 um 22:45 schrieb Mr Flibble:
    You are assuming that I am using pure spinlocks?
    You know what they say about assumptions...

    The other "spinlocks" are not called spinlocks.
    You're posting a lot of source without any context
    which is necessary to understand the code.
    That's sick.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Sat Dec 27 14:49:28 2025
    From Newsgroup: comp.lang.c++

    Am 27.12.2025 um 00:06 schrieb Chris M. Thomasson:
    Lets take an adaptive mutex with a spin count threshold at 1. So, how
    many spins avoided a kernel wait on the mutex object? I created a
    different kind of mutex where a try_lock failure is an opportunity for
    the thread try to do other work. The api for this try work is prefixed
    with try_*. ;^)

    A failed try_lock() is not a reason to burn cycles with PAUSE.
    ItrCOs a signal that someone else is making progress, so yourCOre free to redirect your energy.

    That is why a failed try_lock can be very useful.

    You're thinking about your own ideas and not about what I said.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Sat Dec 27 13:30:48 2025
    From Newsgroup: comp.lang.c++

    On 12/26/2025 1:11 PM, Bonita Montero wrote:
    Am 22.12.2025 um 22:52 schrieb Chris M. Thomasson:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what they say >>> about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while
    trying to avoid a slow path call into a kernel wait.

    These adaptive mutexes rarely prove effective. First, the competing threads only need to hold the mutex for a very short time for the spinning to have any chance of success.Second, the mutex must be locked and released frequently
    so that locking attempts and locking situations often overlap. Both of
    these
    conditions don't occur often.


    We don't really know what complexity a "critical section" might possess
    wrt what it does while the lock is held. We can hope its short and
    sweet... This is why an adaptive mutex usually has a spin count that can
    be altered. A potential nightmare is when a callback is executed while
    holding a lock. I have seen this before. Uggg.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Sun Dec 28 14:41:47 2025
    From Newsgroup: comp.lang.c++

    Am 27.12.2025 um 22:30 schrieb Chris M. Thomasson:
    On 12/26/2025 1:11 PM, Bonita Montero wrote:
    Am 22.12.2025 um 22:52 schrieb Chris M. Thomasson:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what
    they say
    about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while
    trying to avoid a slow path call into a kernel wait.

    These adaptive mutexes rarely prove effective. First, the competing
    threads
    only need to hold the mutex for a very short time for the spinning to
    have
    any chance of success.Second, the mutex must be locked and released
    frequently
    so that locking attempts and locking situations often overlap. Both
    of these
    conditions don't occur often.


    We don't really know what complexity a "critical section" might
    possess wrt what it does while the lock is held. We can hope its short
    and sweet... This is why an adaptive mutex usually has a spin count
    that can be altered. A potential nightmare is when a callback is
    executed while holding a lock. I have seen this before. Uggg.

    Your idea bases implicitly on the assumption that the mutex is hold a very short time and its locked very frequently; otherwise spinning wouldn't make sense. Havong a task that may be completely omitted or may delay the locking
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you won't
    find any.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Sun Dec 28 12:26:01 2025
    From Newsgroup: comp.lang.c++

    On 12/28/2025 5:41 AM, Bonita Montero wrote:
    Am 27.12.2025 um 22:30 schrieb Chris M. Thomasson:
    On 12/26/2025 1:11 PM, Bonita Montero wrote:
    Am 22.12.2025 um 22:52 schrieb Chris M. Thomasson:
    On 12/22/2025 1:45 PM, Mr Flibble wrote:
    On Mon, 22 Dec 2025 03:31:27 +0100, Bonita Montero wrote:

    Pure spinlocks don't make sense in userspace.

    You are assuming that I am using pure spinlocks?-a You know what
    they say
    about assumptions...

    How about adaptive mutexs? Sure they can spin for a little while
    trying to avoid a slow path call into a kernel wait.

    These adaptive mutexes rarely prove effective. First, the competing
    threads
    only need to hold the mutex for a very short time for the spinning to
    have
    any chance of success.Second, the mutex must be locked and released
    frequently
    so that locking attempts and locking situations often overlap. Both
    of these
    conditions don't occur often.


    We don't really know what complexity a "critical section" might
    possess wrt what it does while the lock is held. We can hope its short
    and sweet... This is why an adaptive mutex usually has a spin count
    that can be altered. A potential nightmare is when a callback is
    executed while holding a lock. I have seen this before. Uggg.

    Your idea bases implicitly on the assumption that the mutex is hold a very short time and its locked very frequently; otherwise spinning wouldn't make sense. Havong a task that may be completely omitted or may delay the
    locking

    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?


    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you won't find any.


    Are you talking about adjusting a spin count for an adaptive mutex? Or
    my try to do other lock/wait free work after a try_lock failure?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Mon Dec 29 05:15:15 2025
    From Newsgroup: comp.lang.c++

    Am 28.12.2025 um 21:26 schrieb Chris M. Thomasson:
    Your idea bases implicitly on the assumption that the mutex is hold a
    very
    short time and its locked very frequently; otherwise spinning
    wouldn't make
    sense. Havong a task that may be completely omitted or may delay the
    locking
    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?
    Your idea doesn't make sense because of what I said.
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you
    won't
    find any.

    Are you talking about adjusting a spin count for an adaptive mutex? Or
    my try to do other lock/wait free work after a try_lock failure?

    You should show me real code where your idea applies.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Mon Dec 29 16:22:48 2025
    From Newsgroup: comp.lang.c++

    On 12/28/2025 8:15 PM, Bonita Montero wrote:
    Am 28.12.2025 um 21:26 schrieb Chris M. Thomasson:
    Your idea bases implicitly on the assumption that the mutex is hold a
    very
    short time and its locked very frequently; otherwise spinning
    wouldn't make
    sense. Havong a task that may be completely omitted or may delay the
    locking
    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?
    Your idea doesn't make sense because of what I said.
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you
    won't
    find any.

    Are you talking about adjusting a spin count for an adaptive mutex? Or
    my try to do other lock/wait free work after a try_lock failure?

    You should show me real code where your idea applies.


    My idea of trying to do other lock/wait work after a try_lock, or
    adjusting the spin count for an adaptive mutex, aka:

    https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setcriticalsectionspincount

    ?


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Tue Dec 30 09:52:38 2025
    From Newsgroup: comp.lang.c++

    Am 30.12.2025 um 01:22 schrieb Chris M. Thomasson:
    On 12/28/2025 8:15 PM, Bonita Montero wrote:
    Am 28.12.2025 um 21:26 schrieb Chris M. Thomasson:
    Your idea bases implicitly on the assumption that the mutex is hold
    a very
    short time and its locked very frequently; otherwise spinning
    wouldn't make
    sense. Havong a task that may be completely omitted or may delay
    the locking
    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?
    Your idea doesn't make sense because of what I said.
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee;
    you won't
    find any.

    Are you talking about adjusting a spin count for an adaptive mutex?
    Or my try to do other lock/wait free work after a try_lock failure?

    You should show me real code where your idea applies.

    My idea of trying to do other lock/wait work after a try_lock, or
    adjusting the spin count for an adaptive mutex, aka: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setcriticalsectionspincount

    Your idea has nothing to do with that because SetCriticalSectionSpinCount() doesn't allow alternative tasks.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mr Flibble@flibble@red-dwarf.jmc.corp to comp.lang.c++ on Tue Dec 30 18:21:20 2025
    From Newsgroup: comp.lang.c++

    On Tue, 30 Dec 2025 09:52:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 01:22 schrieb Chris M. Thomasson:
    On 12/28/2025 8:15 PM, Bonita Montero wrote:
    Am 28.12.2025 um 21:26 schrieb Chris M. Thomasson:
    Your idea bases implicitly on the assumption that the mutex is hold
    a very short time and its locked very frequently; otherwise spinning >>>>> wouldn't make sense. Havong a task that may be completely omitted or >>>>> may delay the locking
    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?
    Your idea doesn't make sense because of what I said.
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you >>>>> won't find any.

    Are you talking about adjusting a spin count for an adaptive mutex?
    Or my try to do other lock/wait free work after a try_lock failure?

    You should show me real code where your idea applies.

    My idea of trying to do other lock/wait work after a try_lock, or
    adjusting the spin count for an adaptive mutex, aka:
    https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf- synchapi-setcriticalsectionspincount

    Your idea has nothing to do with that because
    SetCriticalSectionSpinCount()
    doesn't allow alternative tasks.

    You don't need to use OS services/API for a spinlock as the spinning
    happens in userland; you only involve the OS if you revert to a wait for a hybrid spinlock (what mine does).

    /Flibble
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Tue Dec 30 19:44:38 2025
    From Newsgroup: comp.lang.c++

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning
    happens in userland; you only involve the OS if you revert to a wait for a hybrid spinlock (what mine does).

    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mr Flibble@flibble@red-dwarf.jmc.corp to comp.lang.c++ on Tue Dec 30 19:32:39 2025
    From Newsgroup: comp.lang.c++

    On Tue, 30 Dec 2025 19:44:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning
    happens in userland; you only involve the OS if you revert to a wait
    for a hybrid spinlock (what mine does).

    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.

    Wrong, it is called a hybrid spinlock because it spins for a short period (characterized on first use) and then reverts to a wait.

    /Flibble
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Tue Dec 30 21:00:01 2025
    From Newsgroup: comp.lang.c++

    Am 30.12.2025 um 20:32 schrieb Mr Flibble:
    On Tue, 30 Dec 2025 19:44:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning
    happens in userland; you only involve the OS if you revert to a wait
    for a hybrid spinlock (what mine does).
    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.
    Wrong, it is called a hybrid spinlock because it spins for a short period (characterized on first use) and then reverts to a wait.

    /Flibble

    Ok, you're right. But nevertheless it's really rare that its usage makes sense.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mr Flibble@flibble@red-dwarf.jmc.corp to comp.lang.c++ on Tue Dec 30 20:20:42 2025
    From Newsgroup: comp.lang.c++

    On Tue, 30 Dec 2025 21:00:01 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 20:32 schrieb Mr Flibble:
    On Tue, 30 Dec 2025 19:44:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning
    happens in userland; you only involve the OS if you revert to a wait
    for a hybrid spinlock (what mine does).
    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.
    Wrong, it is called a hybrid spinlock because it spins for a short
    period (characterized on first use) and then reverts to a wait.

    /Flibble

    Ok, you're right. But nevertheless it's really rare that its usage makes sense.

    Wrong, hybrid spinlocks are common in:

    * Language runtimes
    * High-performance servers
    * Game engines

    /Flibble
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Tue Dec 30 13:53:28 2025
    From Newsgroup: comp.lang.c++

    On 12/29/2025 4:22 PM, Chris M. Thomasson wrote:
    On 12/28/2025 8:15 PM, Bonita Montero wrote:
    Am 28.12.2025 um 21:26 schrieb Chris M. Thomasson:
    Your idea bases implicitly on the assumption that the mutex is hold
    a very
    short time and its locked very frequently; otherwise spinning
    wouldn't make
    sense. Havong a task that may be completely omitted or may delay the
    locking
    Wrt adpative mutex we can allow one to adjust it to help fit their
    needs. So whats the problem?
    Your idea doesn't make sense because of what I said.
    an arbitrary time doesn't make sense.
    Pleas find any project on the web that does including your idee; you
    won't
    find any.

    Are you talking about adjusting a spin count for an adaptive mutex?
    Or my try to do other lock/wait free work after a try_lock failure?

    You should show me real code where your idea applies.


    My idea of trying to do other lock/wait work after a try_lock, or
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^

    I need to clarify, other lock/wait _free_ work after a try_lock failure.
    This is important. Also, after a try_lock fails we can do a zero timeout
    check on IO. Say a GQCSEX. If it succeeds, we can organize its
    completions in per-thread lists, say, recvs, writes, accepts, connects,
    you know something for batched/cohort scheduling.

    https://learn.microsoft.com/en-us/windows/win32/fileio/getqueuedcompletionstatusex-func

    GQCSEX with a zero timeout. We know if try_lock() fails we have nothing
    to do, or do we? Spinning is just burning cycles waiting on the adaptive
    mutex anyway. Sure a spin count can avoid the kernel, but. Well, why not
    try to do some other work as a back off? Ever heard of adaptive backoff?

    A try_lock failure can be a "signal" for the thread that well, might as
    well try something else before we retry the mutex...



    adjusting the spin count for an adaptive mutex, aka:

    https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf- synchapi-setcriticalsectionspincount

    ?



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to comp.lang.c++ on Tue Dec 30 13:53:54 2025
    From Newsgroup: comp.lang.c++

    On 12/30/2025 12:20 PM, Mr Flibble wrote:
    On Tue, 30 Dec 2025 21:00:01 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 20:32 schrieb Mr Flibble:
    On Tue, 30 Dec 2025 19:44:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning >>>>> happens in userland; you only involve the OS if you revert to a wait >>>>> for a hybrid spinlock (what mine does).
    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.
    Wrong, it is called a hybrid spinlock because it spins for a short
    period (characterized on first use) and then reverts to a wait.

    /Flibble

    Ok, you're right. But nevertheless it's really rare that its usage makes
    sense.

    Wrong, hybrid spinlocks are common in:

    * Language runtimes
    * High-performance servers
    * Game engines

    Ditto.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Wed Dec 31 03:20:30 2025
    From Newsgroup: comp.lang.c++

    Am 30.12.2025 um 21:20 schrieb Mr Flibble:
    On Tue, 30 Dec 2025 21:00:01 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 20:32 schrieb Mr Flibble:
    On Tue, 30 Dec 2025 19:44:38 +0100, Bonita Montero wrote:

    Am 30.12.2025 um 19:21 schrieb Mr Flibble:
    You don't need to use OS services/API for a spinlock as the spinning >>>>> happens in userland; you only involve the OS if you revert to a wait >>>>> for a hybrid spinlock (what mine does).
    A hybrid "spinlock" isn't called spinlock.
    It makes only sense if the mutex is held a very short time and the
    locking occurs at a high frequency. That's are a very rare case.
    Wrong, it is called a hybrid spinlock because it spins for a short
    period (characterized on first use) and then reverts to a wait.

    /Flibble
    Ok, you're right. But nevertheless it's really rare that its usage makes
    sense.
    Wrong, hybrid spinlocks are common in:

    * Language runtimes
    * High-performance servers
    * Game engines

    /Flibble

    They're common in a sense that they're available.
    But as I said they rarely make sense, very rarely.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Bonita Montero@Bonita.Montero@gmail.com to comp.lang.c++ on Wed Dec 31 04:54:38 2025
    From Newsgroup: comp.lang.c++

    Am 30.12.2025 um 21:20 schrieb Mr Flibble:
    Wrong, hybrid spinlocks are common in:
    * Language runtimes
    * High-performance servers
    * Game engines
    /Flibble

    Show me the parameters where spinning makes sense:

    #if defined(_WIN32)
    -a -a #include <Windows.h>
    #elif defined(__unix__)
    -a -a #include <pthread.h>
    -a -a #include <sys/resource.h>
    #endif
    #include <iostream>
    #include <thread>
    #include <vector>
    #include <sstream>

    using namespace std;

    int main( int argc, char **argv )
    {
    #if defined(_WIN32)
    -a -a if( argc < 3 )
    #elif defined(__unix__)
    -a -a if( argc < 2 )
    #endif
    -a -a -a -a return EXIT_FAILURE;
    -a -a unsigned nThreads, spinCount;
    -a -a istringstream iss( argv[1] );
    -a -a iss >> nThreads;
    #if defined(_WIN32)
    -a -a iss.clear();
    -a -a iss.str( argv[2] );
    -a -a iss >> spinCount;
    -a -a CRITICAL_SECTION cs;
    -a -a (void)InitializeCriticalSectionAndSpinCount( &cs, spinCount );
    #elif defined(__unix__)
    -a -a pthread_mutexattr_t attrs;
    -a -a pthread_mutexattr_init( &attrs );
    -a -a pthread_mutexattr_settype( &attrs, PTHREAD_MUTEX_ADAPTIVE_NP );
    -a -a pthread_mutex_t mtx;
    -a -a pthread_mutex_init( &mtx, &attrs );
    #endif
    -a -a vector<jthread> threads;
    -a -a for( unsigned t = nThreads; t; t-- )
    -a -a -a -a threads.emplace_back( [&]
    -a -a -a -a -a -a {
    -a -a -a -a -a -a -a -a for( size_t r = 100'000; r; --r )
    -a -a -a -a -a -a -a -a {
    #if defined(_WIN32)
    -a -a -a -a -a -a -a -a -a -a EnterCriticalSection( &cs );
    -a -a -a -a -a -a -a -a -a -a LeaveCriticalSection( &cs );
    #elif defined(__unix__)
    -a -a -a -a -a -a -a -a -a -a pthread_mutex_lock( &mtx );
    -a -a -a -a -a -a -a -a -a -a pthread_mutex_unlock( &mtx );
    #endif
    -a -a -a -a -a -a -a -a }
    -a -a -a -a -a -a } );
    -a -a threads.resize( 0 );
    #if defined(_WIN32)
    -a -a FILETIME ftDummy, ftKernel, ftUser;
    -a -a GetProcessTimes( GetCurrentProcess(), &ftDummy, &ftDummy,
    &ftKernel, &ftUser );
    -a -a auto real = []( const FILETIME &ft ) -> double { return (double)((uint64_t)ft.dwHighDateTime << 32 | ft.dwLowDateTime) / 1.0e7; };
    -a -a cout << "k: " << real( ftKernel ) << endl;
    -a -a cout << "u: " << real( ftUser ) << endl;
    #elif defined(__unix__)
    -a -a rusage ru;
    -a -a getrusage( RUSAGE_SELF, &ru );
    -a -a auto real = []( timeval &tv ) -> double { return (double)tv.tv_sec
    + (double)tv.tv_usec / 1.0e6; };
    -a -a cout << "k: " << real( ru.ru_stime ) << endl;
    -a -a cout << "u: " << real( ru.ru_utime ) << endl;
    #endif
    }
    --- Synchronet 3.21a-Linux NewsLink 1.2