diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index de068e5..a1539d0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -33,6 +33,7 @@ if(NOT MSVC) APPEND ALL_EXAMPLES task-sender alloc-1 + alloc-2 bulk c++now-allocator c++now-cancel diff --git a/examples/alloc-2.cpp b/examples/alloc-2.cpp new file mode 100644 index 0000000..1877661 --- /dev/null +++ b/examples/alloc-2.cpp @@ -0,0 +1,82 @@ +// examples/alloc-1.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ex = beman::execution; + +// ---------------------------------------------------------------------------- + +struct tls_allocator : std::pmr::polymorphic_allocator { + thread_local static std::pmr::memory_resource* alloc; + + tls_allocator() : std::pmr::polymorphic_allocator(alloc) {} + + static void set(std::pmr::memory_resource* a) { alloc = a; } +}; +thread_local std::pmr::memory_resource* tls_allocator::alloc{std::pmr::new_delete_resource()}; + +// ---------------------------------------------------------------------------- + +void* operator new(std::size_t n) { + auto p = std::malloc(n); + std::cout << " global new(" << n << ")->" << p << "\n"; + return p; +} +void operator delete(void* ptr) noexcept { + std::cout << " global operator delete(" << ptr << ")\n"; + std::free(ptr); +} +void operator delete(void* ptr, std::size_t size) noexcept { + std::cout << " global operator delete(" << ptr << ", " << size << ")\n"; + std::free(ptr); +} + +struct resource : std::pmr::memory_resource { + void* do_allocate(std::size_t n, std::size_t) override { + auto p{std::malloc(n)}; + std::cout << " resource::allocate(" << n << ")->" << p << "\n"; + return p; + } + void do_deallocate(void* p, std::size_t n, std::size_t) override { + std::cout << " resource::deallocate(" << p << ", " << n << ")\n"; + std::free(p); + } + bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; } +}; + +// ---------------------------------------------------------------------------- + +using allocator_type = tls_allocator; +struct alloc_env { + using allocator_type = ::allocator_type; +}; +template +using a_task = ex::task; + +a_task async_fun(int value) { co_return value; } + +int main(int ac, char*[]) { + resource res{}; + + std::cout << "not setting up an allocator:\n"; + ex::sync_wait([ac]() -> a_task<> { + auto result{co_await async_fun(ac)}; + std::cout << " result=" << result << "\n"; + }()); + + std::cout << "setting up an allocator:\n"; + tls_allocator::set(&res); + ex::sync_wait([ac]() -> a_task<> { + auto result{co_await async_fun(ac)}; + std::cout << " result=" << result << "\n"; + }()); +}