-
Notifications
You must be signed in to change notification settings - Fork 267
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
Allow user to customize the new/delete behaviour of Lazy's coroutine state #393
Conversation
跑了几个测试都因为address sanitizer报错退出了,切换到1.3分支编译运行也还是报错,所以测试我也没跑完…… 有啥需要修改补充的吗? Edit: bazel我没用过,那个是我模仿着前面的代码写的。不知道写对没有。 |
尝试了一种更好的办法,可以降低用户使用std::pmr::memory_resource时的开销。根据<memory_resource>的存在与否,分别将lazy_pmr指向std::pmr或async_simple::coro::pmr,使得用户在使用高版本stdlib时没有额外开销。 其中需要注意的是,std::pmr::memory_resource默认对齐alignof(std::max_align_t),而promise的operator new好像不支持传入对齐的参数,所以在operator new这里不知道对齐到多少为好,只好用默认参数了。这可能导致产生过高的对齐限制。 此外代码使用了c++17的 |
emm把除了发布github pages的CI都跑通了。 |
根据@4kangjc的建议,改用PromiseAllocator分配Lazy的coroutine state。由于定义了get_return_object_on_allocation_failure,因此需要noexcept的PromiseAllocator。 我尝试过用
的方式,这样应该可以编译期确定函数是否抛异常,但是clang报错说operator new必须要noexcept才能返回nullptr……没办法只能把模板复制一份改一下了。 另外引入 <algorithm>头文件,不然macos的CI说找不到std::max的定义。(我也不知道为什么原来能过CI……) |
async_simple/coro/PromiseAllocator.h
Outdated
try { | ||
void* const ptr = ::operator new[](size + sizeof(DeallocFn)); | ||
const DeallocFn dealloc = [](void* const ptr, const size_t size) { | ||
::operator delete[](ptr, size + sizeof(DeallocFn)); | ||
}; | ||
::memcpy(static_cast<char*>(ptr) + size, &dealloc, | ||
sizeof(DeallocFn)); | ||
return ptr; | ||
} catch (...) { | ||
return nullptr; | ||
} |
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.
这种写法有点别扭,直接调用 noexcept 的 new 比较好
async_simple/coro/PromiseAllocator.h
Outdated
try { | ||
return Allocate(al, size); | ||
} catch (...) { | ||
return nullptr; | ||
} |
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.
同上,让 Allocate noexcept 比较好
demo_example/pmr_lazy.cpp
Outdated
#if __has_include(<memory_resource>) | ||
ac::Lazy<int> foo( | ||
std::allocator_arg_t /*unused*/, | ||
std::pmr::polymorphic_allocator<> /*coroutine state allocator*/, | ||
int i = 0) { | ||
std::cout << "run with async_simple::coro::pmr::memory_resource" << '\n'; | ||
int test{}; | ||
test = co_await foo(); | ||
std::cout << "a pointer on coroutine frame: " << &test << '\n'; | ||
co_return test + i; | ||
} | ||
#endif |
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.
把这些复制一份改一下放到测试里吧,demo example 很多时候不跑的
写到一半发现一个问题,
这里是不是少加了一个 Edit: 没有问题了,
|
async_simple/coro/PromiseAllocator.h
Outdated
if (ptr == nullptr) { | ||
return; | ||
} |
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.
我们为什么会 delete nullptr?遇到这种情况就是出问题了吧
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.
https://en.cppreference.com/w/cpp/memory/new/operator_delete
In all cases, if ptr is a null pointer, the standard library deallocation functions do nothing. If the pointer passed to the standard library deallocation function was not obtained from the corresponding standard library allocation function, the behavior is undefined.
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.
emm如果觉得没必要模仿标准库行为的话删掉就是了。
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.
我之前到没听说过,那就先这样吧
LGTM. Thanks. |
看起来是使用了多态的分配器。 |
…state
Why
Close #392
What is changing
在LazyPromiseBase里重载operator new/delete以达到控制coroutine state分配行为的目的。
提供async_simple::coro::pmr命名空间:
三个重载的operator new/delete函数:
因为
因此不重载operator new[]算符。
Example
见pmr_lazy.cpp