-
Notifications
You must be signed in to change notification settings - Fork 8
added a TLS using example for task #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ if(NOT MSVC) | |
| APPEND ALL_EXAMPLES | ||
| task-sender | ||
| alloc-1 | ||
| alloc-2 | ||
| bulk | ||
| c++now-allocator | ||
| c++now-cancel | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,82 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // examples/alloc-1.cpp -*-C++-*- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <beman/execution/task.hpp> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <beman/execution/execution.hpp> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <functional> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <iostream> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <memory> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <memory_resource> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <new> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <cstdlib> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <utility> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace ex = beman::execution; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ---------------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct tls_allocator : std::pmr::polymorphic_allocator<std::byte> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| thread_local static std::pmr::memory_resource* alloc; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tls_allocator() : std::pmr::polymorphic_allocator<std::byte>(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"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+31
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto p = std::malloc(n); | |
| std::cout << " global new(" << n << ")->" << p << "\n"; | |
| void* p = std::malloc(n); | |
| std::cout << " global new(" << n << ")->" << p << "\n"; | |
| if (!p) { | |
| throw std::bad_alloc(); | |
| } |
Copilot
AI
Mar 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::pmr::memory_resource::do_allocate(bytes, alignment) must honor the requested alignment. Ignoring the alignment parameter and using malloc can return misaligned storage for over-aligned allocations. Use an aligned allocation strategy (e.g., ::operator new(bytes, std::align_val_t(alignment)) + matching aligned delete, or std::aligned_alloc where available).
| 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); | |
| void* do_allocate(std::size_t n, std::size_t alignment) override { | |
| void* p = nullptr; | |
| #if defined(__cpp_aligned_new) | |
| if (alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { | |
| p = ::operator new(n, std::align_val_t(alignment)); | |
| } else | |
| #endif | |
| { | |
| p = ::operator new(n); | |
| } | |
| std::cout << " resource::allocate(" << n << ")->" << p << "\n"; | |
| return p; | |
| } | |
| void do_deallocate(void* p, std::size_t n, std::size_t alignment) override { | |
| std::cout << " resource::deallocate(" << p << ", " << n << ")\n"; | |
| #if defined(__cpp_aligned_new) | |
| if (alignment > __STDCPP_DEFAULT_NEW_ALIGNMENT__) { | |
| ::operator delete(p, n, std::align_val_t(alignment)); | |
| } else | |
| #endif | |
| { | |
| ::operator delete(p, n); | |
| } |
Copilot
AI
Mar 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tls_allocator::set(&res) stores a pointer to a stack resource in a thread_local that outlives res. Even though this example exits soon after, leaving a thread_local pointing at a soon-to-be-destroyed object is easy to copy/paste into real code and becomes a dangling pointer hazard. Consider resetting back to std::pmr::new_delete_resource() after the sync_wait, or wrap the change in an RAII guard object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File header comment says
examples/alloc-1.cppbut this isalloc-2.cpp, which can confuse readers and tooling that relies on the header banner. Update the comment to match the actual filename.