Tencent/phxrpc

Why we split the pointer to two `uint32_t`s in `UThreadContextSystem :: UThreadFuncWrapper`?·

Wizmann opened this issue · 1 comments

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_();
    }
}

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.

http://man7.org/linux/man-pages/man3/makecontext.3.html