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
signature.asc
Description: This is a digitally signed message part