Why we split the pointer to two `uint32_t`s in `UThreadContextSystem :: UThreadFuncWrapper`?·
Wizmann opened this issue · 1 comments
Wizmann commented
in file uthread_context_system.cpp
, we have a function called UThreadFuncWrapper
. I'm confused why we pass high bits and low bits of this
pointer rather than passing the whole this
pointer into the wrapper. Is there any concern about that?
Thanks for your reply.
void UThreadContextSystem :: Make(UThreadFunc_t func, void * args) {
func_ = func;
args_ = args;
getcontext(&context_);
context_.uc_stack.ss_sp = stack_.top();
context_.uc_stack.ss_size = stack_.size();
context_.uc_stack.ss_flags = 0;
context_.uc_link = GetMainContext();
uintptr_t ptr = (uintptr_t)this;
makecontext(&context_, (void (*)(void))UThreadContextSystem::UThreadFuncWrapper,
2, (uint32_t)ptr, (uint32_t)(ptr >> 32)); // we split `this` pointer into two parts
}
void UThreadContextSystem :: UThreadFuncWrapper(uint32_t low32, uint32_t high32) {
uintptr_t ptr = (uintptr_t)low32 | ((uintptr_t) high32 << 32); // then we put it together again
UThreadContextSystem * uc = (UThreadContextSystem *)ptr;
uc->func_(uc->args_);
if (uc->callback_ != nullptr) {
uc->callback_();
}
}
Wizmann commented
When this context is later activated (using setcontext(3) or
swapcontext()) the function func is called, and passed the series of
integer (int) arguments that follow argc; the caller must specify the
number of these arguments in argc. When this function returns, the
successor context is activated. If the successor context pointer is
NULL, the thread exits.