diff options
author | eldritch horrors <pennae@lix.systems> | 2024-05-11 00:49:22 +0200 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-07-16 01:50:16 +0000 |
commit | dfedbc154f08bc025706847b275333526f87579b (patch) | |
tree | 8626dcdd064fa220d4e3fe053af0f9436b768dfa /src | |
parent | d094dd0396a9ec0b4ce725412cc73c6d9af31021 (diff) |
remove sourceToSink, sinkToSource, and boehm patch
Change-Id: I1379841299713175d0225b82a67f50660f9eb5e2
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval.cc | 64 | ||||
-rw-r--r-- | src/libutil/serialise.cc | 171 | ||||
-rw-r--r-- | src/libutil/serialise.hh | 8 |
3 files changed, 0 insertions, 243 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ced92136b..77b46c2ed 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -192,42 +192,6 @@ static void * oomHandler(size_t requested) throw std::bad_alloc(); } -class BoehmGCStackAllocator : public StackAllocator { - boost::coroutines2::protected_fixedsize_stack stack { - // We allocate 8 MB, the default max stack size on NixOS. - // A smaller stack might be quicker to allocate but reduces the stack - // depth available for source filter expressions etc. - std::max(boost::context::stack_traits::default_size(), static_cast<std::size_t>(8 * 1024 * 1024)) - }; - - // This is specific to boost::coroutines2::protected_fixedsize_stack. - // The stack protection page is included in sctx.size, so we have to - // subtract one page size from the stack size. - std::size_t pfss_usable_stack_size(boost::context::stack_context &sctx) { - return sctx.size - boost::context::stack_traits::page_size(); - } - - public: - boost::context::stack_context allocate() override { - auto sctx = stack.allocate(); - - // Stacks generally start at a high address and grow to lower addresses. - // Architectures that do the opposite are rare; in fact so rare that - // boost_routine does not implement it. - // So we subtract the stack size. - GC_add_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp); - return sctx; - } - - void deallocate(boost::context::stack_context sctx) override { - GC_remove_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp); - stack.deallocate(sctx); - } - -}; - -static BoehmGCStackAllocator boehmGCStackAllocator; - #endif @@ -243,23 +207,6 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env) } } -#if HAVE_BOEHMGC -/* Disable GC while this object lives. Used by CoroutineContext. - * - * Boehm keeps a count of GC_disable() and GC_enable() calls, - * and only enables GC when the count matches. - */ -class BoehmDisableGC { -public: - BoehmDisableGC() { - GC_disable(); - }; - ~BoehmDisableGC() { - GC_enable(); - }; -}; -#endif - static bool gcInitialised = false; void initGC() @@ -281,17 +228,6 @@ void initGC() GC_set_oom_fn(oomHandler); - StackAllocator::defaultAllocator = &boehmGCStackAllocator; - - -#if NIX_BOEHM_PATCH_VERSION != 1 - printTalkative("Unpatched BoehmGC, disabling GC inside coroutines"); - /* Used to disable GC when entering coroutines on macOS */ - create_coro_gc_hook = []() -> std::shared_ptr<void> { - return std::make_shared<BoehmDisableGC>(); - }; -#endif - /* Set the initial heap size to something fairly big (25% of physical RAM, up to a maximum of 384 MiB) so that in most cases we don't need to garbage collect at all. (Collection has a diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 11bc183cc..a294a7ea1 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -149,177 +149,6 @@ size_t StringSource::read(char * data, size_t len) } -#if BOOST_VERSION >= 106300 && BOOST_VERSION < 106600 -#error Coroutines are broken in this version of Boost! -#endif - -/* A concrete datatype allow virtual dispatch of stack allocation methods. */ -struct VirtualStackAllocator { - StackAllocator *allocator = StackAllocator::defaultAllocator; - - boost::context::stack_context allocate() { - return allocator->allocate(); - } - - void deallocate(boost::context::stack_context sctx) { - allocator->deallocate(sctx); - } -}; - - -/* This class reifies the default boost coroutine stack allocation strategy with - a virtual interface. */ -class DefaultStackAllocator : public StackAllocator { - boost::coroutines2::default_stack stack; - - boost::context::stack_context allocate() { - return stack.allocate(); - } - - void deallocate(boost::context::stack_context sctx) { - stack.deallocate(sctx); - } -}; - -static DefaultStackAllocator defaultAllocatorSingleton; - -StackAllocator *StackAllocator::defaultAllocator = &defaultAllocatorSingleton; - - -std::shared_ptr<void> (*create_coro_gc_hook)() = []() -> std::shared_ptr<void> { - return {}; -}; - -/* This class is used for entry and exit hooks on coroutines */ -class CoroutineContext { - /* Disable GC when entering the coroutine without the boehm patch, - * since it doesn't find the main thread stack in this case. - * std::shared_ptr<void> performs type-erasure, so it will call the right - * deleter. */ - const std::shared_ptr<void> coro_gc_hook = create_coro_gc_hook(); -public: - CoroutineContext() {}; - ~CoroutineContext() {}; -}; - -std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun) -{ - struct SourceToSink : FinishSink - { - typedef boost::coroutines2::coroutine<bool> coro_t; - - std::function<void(Source &)> fun; - std::optional<coro_t::push_type> coro; - - SourceToSink(std::function<void(Source &)> fun) : fun(fun) - { - } - - std::string_view cur; - - void operator () (std::string_view in) override - { - if (in.empty()) return; - cur = in; - - if (!coro) { - CoroutineContext ctx; - coro = coro_t::push_type(VirtualStackAllocator{}, [&](coro_t::pull_type & yield) { - LambdaSource source([&](char *out, size_t out_len) { - if (cur.empty()) { - yield(); - if (yield.get()) { - throw EndOfFile("coroutine exhausted"); - } - } - - size_t n = std::min(cur.size(), out_len); - memcpy(out, cur.data(), n); - cur.remove_prefix(n); - return n; - }); - fun(source); - }); - } - - if (!*coro) { abort(); } - - if (!cur.empty()) { - CoroutineContext ctx; - (*coro)(false); - } - } - - void finish() override - { - if (!coro) return; - if (!*coro) abort(); - { - CoroutineContext ctx; - (*coro)(true); - } - if (*coro) abort(); - } - }; - - return std::make_unique<SourceToSink>(fun); -} - - -std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun) -{ - struct SinkToSource : Source - { - typedef boost::coroutines2::coroutine<std::string> coro_t; - - std::function<void(Sink &)> fun; - std::optional<coro_t::pull_type> coro; - - SinkToSource(std::function<void(Sink &)> fun) - : fun(fun) - { - } - - std::string cur; - size_t pos = 0; - - size_t read(char * data, size_t len) override - { - if (!coro) { - CoroutineContext ctx; - coro = coro_t::pull_type(VirtualStackAllocator{}, [&](coro_t::push_type & yield) { - LambdaSink sink([&](std::string_view data) { - if (!data.empty()) yield(std::string(data)); - }); - fun(sink); - }); - } - - if (!*coro) { - throw EndOfFile("coroutine has finished"); - } - - if (pos == cur.size()) { - if (!cur.empty()) { - CoroutineContext ctx; - (*coro)(); - } - cur = coro->get(); - pos = 0; - } - - auto n = std::min(cur.size() - pos, len); - memcpy(data, cur.data() + pos, n); - pos += n; - - return n; - } - }; - - return std::make_unique<SinkToSource>(fun); -} - - void writePadding(size_t len, Sink & sink) { if (len % 8) { diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 874c67b75..9b1892bbb 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -362,14 +362,6 @@ private: Bytes buf{}; }; -std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun); - -/** - * Convert a function that feeds data into a Sink into a Source. The - * Source executes the function as a coroutine. - */ -std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun); - inline Sink & operator<<(Sink & sink, Generator<Bytes> && g) { while (auto buffer = g.next()) { |