void Service::Create(fiber_func func, void *data, int32_t stacksize, const char* name, Fiber** retVal) { Fiber *fb; void **stack; stacksize = (stacksize + FB_STK_ALIGN - 1) & ~(FB_STK_ALIGN - 1); #ifdef WIN32 fb = (Fiber *) VirtualAlloc(NULL, stacksize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); #else fb = (Fiber *) malloc(stacksize); #endif if (fb == NULL) return; stack = (void **) fb + stacksize / sizeof(void *) - 5; new(fb) Fiber(s_service, data); fb->m_cntxt.ip = (intptr_t) fiber_proc; fb->m_cntxt.sp = (intptr_t) stack; #if defined(x64) #ifdef _WIN32 fb->m_cntxt.Rcx = (intptr_t) func; fb->m_cntxt.Rdx = (intptr_t) fb; #else fb->m_cntxt.Rdi = (intptr_t) func; fb->m_cntxt.Rsi = (intptr_t) fb; #endif #elif defined(I386) stack[1] = (void *)func; stack[2] = fb; #elif defined(arm) fb->m_cntxt.r0 = (intptr_t) func; fb->m_cntxt.r1 = (intptr_t) fb; #endif #ifdef DEBUG s_locker.lock(); s_fibers.putTail(&fb->m_link); s_locker.unlock(); #endif if (retVal) { *retVal = fb; fb->Ref(); } fb->Ref(); fb->resume(); }
Fiber *Service::CreateFiber(void *(*func)(void *), void *data, int stacksize) { Fiber *fb; void **stack; stacksize = (stacksize + FB_STK_ALIGN - 1) & ~(FB_STK_ALIGN - 1); #ifdef WIN32 fb = (Fiber *) VirtualAlloc(NULL, stacksize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); #else fb = (Fiber *) malloc(stacksize); #endif if (fb == NULL) return NULL; stack = (void **) fb + stacksize / sizeof(void *) - 5; memset(fb, 0, sizeof(Fiber)); #if defined(x64) fb->m_cntxt.Rip = (unsigned long long) fiber_proc; fb->m_cntxt.Rsp = (unsigned long long) stack; #ifdef _WIN32 fb->m_cntxt.Rcx = (unsigned long long) func; fb->m_cntxt.Rdx = (unsigned long long) data; #else fb->m_cntxt.Rdi = (unsigned long long) func; fb->m_cntxt.Rsi = (unsigned long long) data; #endif #elif defined(I386) fb->m_cntxt.Eip = (unsigned long) fiber_proc; fb->m_cntxt.Esp = (unsigned long) stack; stack[1] = (void *)func; stack[2] = data; #elif defined(arm) fb->m_cntxt.r14 = (unsigned long) fiber_proc; fb->m_cntxt.r13 = (unsigned long) stack; fb->m_cntxt.r0 = (unsigned long) func; fb->m_cntxt.r1 = (unsigned long) data; #endif root->m_resume.put(fb); fb->Ref(); fb->Ref(); return fb; }