Skip to content

Conversation

@beef9999
Copy link
Collaborator

@beef9999 beef9999 commented Oct 21, 2025

use_pooled_stack_allocator可能在程序很早的地方被调用,然而,PooledStackAllocator是一个thread-local变量,由于是按需使用alloc/dealloc,所以这个变量的初始化也很晚。

在程序结束的时候,PooledStackAllocator会优先于其他thread-local模块析构,于是造成了这些thread-local模块(已经使用了它分配的内存)产生coredump。

这个MR在use_pooled_stack_allocator的时候就初始化thread-local变量,并且把 set_thread_stack_allocator 放到 thread.h 模块,简化一些 stack-allocator.h 的代码


use_pooled_stack_allocator may be called very early in the program. However, PooledStackAllocator is a thread-local variable, and due to the on-demand use of alloc/dealloc, the initialization of this variable is also very late.​
At the end of the program, PooledStackAllocator will be destructed before other thread-local modules, which causes some thread-local modules (that have used the memory allocated by it) to generate coredumps.​
This MR initializes the thread-local variable when use_pooled_stack_allocator is called, and moves set_thread_stack_allocator to the thread.h module to simplify some code in stack-allocator.h.

@beef9999 beef9999 requested review from Coldwings and lihuiba October 21, 2025 15:03
Copy link
Collaborator

@Coldwings Coldwings left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use_pooled_stack_allocator是需要严格要求首次photon init是配置的(或者在vcpu_init之前进行配置),并且不允许改回。因此这个配置的处理才是单向的(仅能开启,不能通过设置为false进行关闭)。

对于明确知道栈分配器配置的用户场景,使用单独的photon::set_thread_stack_allocator可以自由控制更改;对于非此类用户,应当避免在使用默认option去初始化主线程外的vcpu时,由于使用默认配置而改回,这样会造成pool泄漏、释放不正确等问题。

if (options.use_pooled_stack_allocator) {
use_pooled_stack_allocator();
} else {
use_default_stack_allocator();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each vcpu will call photon_init, and use_pooled_stack_allocator is a global config.
This change may leads to user set-up pooled-stack-allocator and then unset. (by initialize another vcpu without setting use_pooled_stack_allocator. That is highly risky.

size_t pooled_stack_trim_threshold(size_t x);
void use_pooled_stack_allocator() {
get_pooled_stack_allocator();
std::call_once(init_once_flag, [] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is a one-way setter and always put same value, is it really need to use a std::call_once?

}

int vcpu_init(uint64_t flags) {
if (unlikely(!photon_thread_alloc || !photon_thread_dealloc)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only problem is here:
once vcpu_init called in a global constructor, it might be called before photon_thread_alloc construct or library load.

that may cause delegate photon_thread_alloc become an empty delegate and unable to be called, result in allocation failure and segment fault.

@beef9999 beef9999 closed this Nov 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants