lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: event queue with thread for c++


From: David Kastrup
Subject: Re: event queue with thread for c++
Date: Sat, 08 Feb 2020 16:23:04 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Jonas Hahnfeld via Discussions on LilyPond development
<address@hidden> writes:

> Am Freitag, den 07.02.2020, 19:26 +0100 schrieb Han-Wen Nienhuys:
>> Hey Dan,
>> 
>> I thought you might know this.
>> 
>> To do 
>> https://codereview.appspot.com/561390043/
>>  properly, I have to expand
>> the heap when GC notifies us that a collection took place. Unfortunately,
>> libgc notifications are done with the garbage collector lock held. So I'll
>> need schedule a call to GC_expand_heap on a different thread.
>> 
>> Would you know what is the best way to do this in C++ nowadays?
>
> If I understand the information correctly, it would be enough to pass
> data from the callback to e.g. the main thread, right?
>
> When a single boolean is sufficient (ie call that function now), I'd
> start with std::atomic_flag which is guaranteed to be lock-free. Upon
> reading the documentation, the semantics are a bit weird (ie
> test_and_set sets the flag to true). So you'd need flag.clear() in the
> callback and if (!flag.test_and_set()) GC_expand_heap(...) in the main
> code. A thin layer around it may improve readability, ie doing the
> inverted logic in a struct / class. Alternatively you can use
> std::atomic<bool> which is probably lock-free on all architectures we
> care about.
>
> If you need to transport more than that (ie an integer), the more
> generic std::atomic<T> might be a choice. For your concrete case,
> declare the following:
> static std::atomic_size_t expand_heap = ATOMIC_VAR_INIT(0);
> then in the callback:
> expand_heap = <<<computed argument>>>;
> and in the main thread:
> // Benign race condition: Check that there is something to do to avoid
> // writes if the variable is already 0. The value is then retrieved
> // via exchange() below which is atomic.
> if (expand_heap != 0) {
>   size_t arg = expand_heap.exchange(0);
>   if (arg != 0) {
>     GC_expand_hp(arg);
>   }
> }
>
> Does this already solve your needs?
> Jonas

It's worth pointing out that almost _all_ of our Scheme-level
allocations are routed through the Smob_core class, so doing the heap
extension _there_ when one passes there next should be workable.  While
the code certainly does allocate non-Smob SCM objects a lot as well (by
calling things like scm_cons), the smobbed ones should be worked often
enough that extending the heap then should not cause too much churn.

-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]