/* * Free function. Saves the current context in @p from * and restores the context in @p to. On windows the from * parameter is ignored. The current context is saved on the * current fiber. * Note that if the current thread is not a fiber, it will be * converted to fiber on the fly on call and unconverted before * return. This is expensive. The user should convert the * current thread to a fiber once on thread creation for better performance. * Note that we can't leave the thread unconverted on return or else we * will leak resources on thread destruction. Do the right thing by * default. */ friend void swap_context(fibers_context_impl_base& from, const fibers_context_impl_base& to, default_hint) { if(!is_fiber()) { HPX_ASSERT(from.m_ctx == 0); from.m_ctx = ConvertThreadToFiber(0); HPX_ASSERT(from.m_ctx != 0); #if HPX_HAVE_SWAP_CONTEXT_EMULATION != 0 switch_to_fiber(to.m_ctx); #else SwitchToFiber(to.m_ctx); #endif BOOL result = ConvertFiberToThread(); HPX_ASSERT(result); HPX_UNUSED(result); from.m_ctx = 0; } else { bool call_from_main = from.m_ctx == 0; if(call_from_main) from.m_ctx = GetCurrentFiber(); #if HPX_HAVE_SWAP_CONTEXT_EMULATION != 0 switch_to_fiber(to.m_ctx); #else SwitchToFiber(to.m_ctx); #endif if(call_from_main) from.m_ctx = 0; } }
unsigned int __stdcall threadStart(void* threadData) { #ifdef _DEBUG //set thread debug name struct { DWORD type; LPCSTR pName; DWORD threadID; DWORD flags; } info; char name[64]; sprintf(name, "thread_%i", ((Thread*)threadData) - g_threads); info.type = 0x1000; info.pName = name; info.threadID = -1; info.flags = 0; RaiseException(0x406D1388, 0, sizeof(info), (const ULONG_PTR*)&info); #endif TlsSetValue(g_threadData, threadData); ConvertThreadToFiber(0); runNewFiber(); ConvertFiberToThread(); return 0; }
void Processor::coreEntryPoint(Core *core) { tCurrentCore = core; core->primaryFiber = ConvertThreadToFiber(NULL); while (mRunning) { std::unique_lock<std::mutex> lock(mMutex); if (auto fiber = peekNextFiber(core->id)) { // Remove fiber from schedule queue mFiberQueue.erase(std::remove(mFiberQueue.begin(), mFiberQueue.end(), fiber), mFiberQueue.end()); // Switch to fiber core->currentFiber = fiber; fiber->coreID = core->id; fiber->parentFiber = core->primaryFiber; fiber->thread->state = OSThreadState::Running; lock.unlock(); gLog->trace("Core {} enter thread {}", core->id, fiber->thread->id); SwitchToFiber(fiber->handle); } else { // Wait for a valid fiber gLog->trace("Core {} wait for thread", core->id); mCondition.wait(lock); } } }
struct ff_arch_fiber *ff_arch_fiber_initialize() { main_fiber.handle = ConvertThreadToFiber((LPVOID) NULL); ff_assert(main_fiber.handle != NULL); return &main_fiber; }
INT32 CoInit() { void * pFiberContext = ConvertThreadToFiber(NULL); MsgAssert_ReF1(pFiberContext, "Create fiber error."); g_FiberContext.set(pFiberContext); return 0; }
static void init_main_thread(void *addr) { struct regs *context = (struct regs*)addr; /* we must convert the current main thread to a fiber to be able to * schedule other fibers */ context->uc = ConvertThreadToFiber(NULL); context->stack_size = 0; }
TContMachineContext::TContMachineContext() : Fiber_(ConvertThreadToFiber(this)) , MainFiber_(true) { if (!Fiber_) { ythrow yexception() << "fiber error"; } }
Coroutine *qemu_coroutine_self(void) { if (!current) { current = &leader.base; leader.fiber = ConvertThreadToFiber(NULL); } return current; }
void Coroutine::init() { if (!IsThreadAFiber()) pImpl->pReturnFiber = ConvertThreadToFiber(NULL); else pImpl->pReturnFiber = GetCurrentFiber(); pImpl->pFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)Coroutine::Anonymous::coroutineEntry, pImpl.get()); }
inline void create_main_fiber(fiber_t& fib) { fib = ConvertThreadToFiber(0); if (0 == fib) { unsigned long err = ::GetLastError(); (void)err; throw std::logic_error("you must start simulation inside a thread (not a fiber)"); } }
/*--------------------------------------------------------------------------*/ void mtarch_init(void) { #ifdef __CYGWIN__ main_fiber = ConvertThreadToFiber(NULL); #endif /* __CYGWIN__ */ }
/*--------------------------------------------------------------------------*/ void mtarch_init(void) { #if defined(_WIN32) || defined(__CYGWIN__) main_fiber = ConvertThreadToFiber(NULL); #endif /* _WIN32 || __CYGWIN__ */ }
struct schedule * coroutine_open(void) { struct schedule *S = (struct schedule*)malloc(sizeof(*S)); S->nco = 0; S->cap = DEFAULT_COROUTINE; S->running = -1; S->co = (struct coroutine**)malloc(sizeof(struct coroutine *) * S->cap); memset(S->co, 0, sizeof(struct coroutine *) * S->cap); S->main = ConvertThreadToFiber(NULL); return S; }
static void MainThreadInit() { PVOID pData = GetCurrentFiber(); if (pData == (void*)0x1E00) // magic { LPVOID h = ConvertThreadToFiber( &MainFiberId ); ESS_ASSERT(h != 0); ESS_ASSERT( GetFiberData() == &MainFiberId ); } }
void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread) { thread->md.fiber_id = ConvertThreadToFiber(NULL); PR_ASSERT(thread->md.fiber_id); _MD_SET_CURRENT_THREAD(thread); _MD_SET_LAST_THREAD(thread); thread->no_sched = 1; return; }
int LWP_InitializeProcessSupport(int priority, PROCESS *pid) { PROCESS pcb; register int i; char* value; Debug(0, ("Entered LWP_InitializeProcessSupport")) if (lwp_init != NULL) return LWP_SUCCESS; if (priority >= MAX_PRIORITIES) return LWP_EBADPRI; pcb = (PROCESS)malloc(sizeof(*pcb)); if (pcb == NULL) Abort_LWP("Insufficient Storage to Initialize LWP PCB"); (void) memset((void*)pcb, 0, sizeof(*pcb)); pcb->fiber = ConvertThreadToFiber(pcb); if (pcb == NULL) Abort_LWP("Cannot convert main thread to LWP fiber"); lwp_init = (struct lwp_ctl *) malloc(sizeof(struct lwp_ctl)); if (lwp_init == NULL) Abort_LWP("Insufficient Storage to Initialize LWP CTL"); (void) memset((void*)lwp_init, 0, sizeof(struct lwp_ctl)); for (i=0; i<MAX_PRIORITIES; i++) { runnable[i].head = NULL; runnable[i].count = 0; } blocked.head = NULL; blocked.count = 0; LWPANCHOR.processcnt = 1; LWPANCHOR.outerpid = pcb; LWPANCHOR.outersp = NULL; Initialize_PCB(pcb, priority, 0, NULL, NULL, "Main Process [created by LWP]"); lwp_cpptr = pcb; Debug(10, ("Init: Insert 0x%p into runnable at priority %d\n", pcb, priority)) insert(pcb, &runnable[priority]); if ( ( value = getenv("AFS_LWP_STACK_SIZE")) == NULL ) lwp_MinStackSize = AFS_LWP_MINSTACKSIZE; else lwp_MinStackSize = (AFS_LWP_MINSTACKSIZE>atoi(value)? AFS_LWP_MINSTACKSIZE : atoi(value)); *pid = pcb; return LWP_SUCCESS; }
int main(int argc, WCHAR* argv[]) { fiberA = CreateFiber(0, (LPFIBER_START_ROUTINE)FiberA, (LPVOID)0); fiberB = CreateFiber(0, (LPFIBER_START_ROUTINE)FiberB, (LPVOID)0); mainFiber = ConvertThreadToFiber(NULL); for (int i = 0; i < 20; i++) { SwitchToFiber(fiberA); SwitchToFiber(fiberB); Sleep(100); } return 0; }
SafeThreadToFibre (LPVOID &fiber) :m_converted(false) ,m_fiber(fiber) { fiber = GetCurrentFiber (); if ((fiber == 0) || (fiber == (LPVOID)0x1E00/*see boost*/)) { fiber = ConvertThreadToFiber (NULL); if (!fiber) throw 0; m_converted = true; } }
void coro_transfer (coro_context *prev, coro_context *next) { if (!prev->fiber) { prev->fiber = GetCurrentFiber (); if (prev->fiber == 0 || prev->fiber == (void *)0x1e00) prev->fiber = ConvertThreadToFiber (0); } SwitchToFiber (next->fiber); }
int main(int argc, const char* argv[]) { InitCommonControls(); if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "wb", stdout); freopen("CONOUT$", "wb", stderr); } uifiber = ConvertThreadToFiber(NULL); assert(uifiber); appfiber = CreateFiber(0, application_cb, NULL); assert(appfiber); realargc = argc; realargv = argv; /* Run the application fiber. This will deschedule when it wants an * event. */ SwitchToFiber(appfiber); /* And now the event loop. */ int oldtimeout = -1; for (;;) { MSG msg; dpy_flushkeys(); if (timeout != oldtimeout) { if (timeout == -1) KillTimer(window, TIMEOUT_TIMER_ID); else SetTimer(window, TIMEOUT_TIMER_ID, timeout*1000, NULL); oldtimeout = timeout; } GetMessageW(&msg, NULL, 0, 0); if (DispatchMessageW(&msg) == 0) TranslateMessage(&msg); } return 0; }
/* * implementation for context_init */ void context_init() { PVOID pTopFiber = (top_context == NULL || top_context != current_context)? NULL: top_context->pFiber; context_deinit(); /* * there is strange but fibers always exist * PVOID pCurrentFiber = GetCurrentFiber(); * if (pCurrentFiber != NULL) DeleteFiber(pCurrentFiber); */ current_context = top_context = context_alloc(); if (top_context != NULL) top_context->pFiber = (pTopFiber == NULL)? ConvertThreadToFiber(NULL): pTopFiber; return; }
void Coro_initializeMainCoro(Coro *self) { self->isMain = 1; #ifdef USE_FIBERS // We must convert the current thread into a fiber if it hasn't already been done. if ((LPVOID) 0x1e00 == GetCurrentFiber()) // value returned when not a fiber { // Make this thread a fiber and set its data field to the main coro's address ConvertThreadToFiber(self); } // Make the main coro represent the current fiber self->fiber = GetCurrentFiber(); #endif }
int coroutine_init(struct coroutine *co) { if (leader.fiber == NULL) { leader.fiber = ConvertThreadToFiber(&leader); if (leader.fiber == NULL) return -1; } co->fiber = CreateFiber(0, &coroutine_trampoline, co); co->ret = 0; if (co->fiber == NULL) return -1; return 0; }
bool FiberManager::InitMain(const FiberInitStruct& init) { const unsigned numLowPriorityWorkers = lptk::Max(1u, init.numWorkerThreads); const unsigned numHighPriorityWorkers = init.numHighPriorityWorkerThreads; const unsigned numWorkers = numLowPriorityWorkers + numHighPriorityWorkers; m_workerThreads.reserve(numWorkers-1); m_threadData.resize(numWorkers); for (unsigned i = 0; i < numWorkers; ++i) { auto& threadData = m_threadData[i]; threadData.m_priority = i < numLowPriorityWorkers ? 0 : 1; const auto numSmallFibers = lptk::Max(1u, threadData.m_priority == 0 ? init.numSmallFibersPerThread : init.numSmallFibersPerHighPriorityThread); if (!threadData.m_smallStackPool.Init(int(i), numSmallFibers, init.smallFiberStackSize)) { return false; } const auto numLargeFibers = lptk::Max(1u, threadData.m_priority == 0 ? init.numLargeFibersPerThread : init.numLargeFibersPerHighPriorityThread); if (!threadData.m_largeStackPool.Init(int(i), numSmallFibers, init.largeFiberStackSize)) { return false; } threadData.m_executing = make_unique<CircularQueue<Fiber*>>(numSmallFibers + numLargeFibers); if (i == 0) // main thread gets to be a fiber too! { s_currentThread = 0; #if defined(WINDOWS) threadData.m_mainFiber = ConvertThreadToFiber(nullptr); #elif defined(LINUX) #error linux version of FiberManager::InitThread not yet implemented #endif } else { m_workerThreads.push_back(lptk::Thread(WorkerMain, this, i)); } } return true; }
// Entry point of CPU Core threads void Processor::coreEntryPoint(Core *core) { tCurrentCore = core; platform::ui::initialiseCore(core->id); core->primaryFiber = ConvertThreadToFiber(NULL); while (mRunning) { // Intentionally do this before the lock... gDebugControl.maybeBreak(0, nullptr, core->id); std::unique_lock<std::mutex> lock { mMutex }; // Free any fibers which need to be deleted for (auto fiber : core->mFiberDeleteList) { delete fiber; } core->mFiberDeleteList.clear(); if (auto fiber = peekNextFiberNoLock(core->id)) { // Remove fiber from schedule queue mFiberQueue.erase(std::remove(mFiberQueue.begin(), mFiberQueue.end(), fiber), mFiberQueue.end()); // Switch to fiber core->currentFiber = fiber; fiber->coreID = core->id; fiber->parentFiber = core->primaryFiber; fiber->thread->state = OSThreadState::Running; lock.unlock(); gLog->trace("Core {} enter thread {}", core->id, fiber->thread->id); SwitchToFiber(fiber->handle); } else if (core->interrupt) { // Switch to the interrupt thread for any waiting interrupts lock.unlock(); handleInterrupt(); } else { // Wait for a valid fiber gLog->trace("Core {} wait for thread", core->id); mCondition.wait(lock); } } }
void uthread::enter_thread() { uthread_impl *impl = new uthread_impl(); void *f = ConvertThreadToFiber(impl); if(!f) { delete impl; DeleteFiber(f); return; } impl->fiber = f; if(!dry_thread) { dry_thread = uthread_create(uthread_dry, nullptr); dry_thread->mSuspended = true; } enter_thread_common(); }
int pthread_np_convert_self_to_fiber() { pthread_t pth = pthread_self(); if (!pth) return 1; if (!pth->fiber) { void* fiber = GetCurrentFiber(); /* Beware: undocumented (but widely used) method below to check if the thread is already converted. */ if (fiber != NULL && fiber != (void*)0x1E00) { pth->fiber = fiber; pth->own_fiber = 0; } else { pth->fiber = ConvertThreadToFiber(pth); pth->own_fiber = 1; } if (!pth->fiber) return 1; } return 0; }
int async_fibre_init_dispatcher(async_fibre *fibre) { LPVOID dispatcher; dispatcher = (LPVOID)TlsGetValue(asyncwindispatch); if (dispatcher == NULL) { fibre->fibre = ConvertThreadToFiber(NULL); if (fibre->fibre == NULL) { fibre->converted = 0; fibre->fibre = GetCurrentFiber(); if (fibre->fibre == NULL) return 0; } else { fibre->converted = 1; } if (TlsSetValue(asyncwindispatch, (LPVOID)fibre->fibre) == 0) return 0; } else { fibre->fibre = dispatcher; } return 1; }
sc_cor_pkg_fiber::sc_cor_pkg_fiber( sc_simcontext* simc ) : sc_cor_pkg( simc ) { if( ++ instance_count == 1 ) { // initialize the main coroutine assert( main_cor.m_fiber == 0 ); main_cor.m_fiber = ConvertThreadToFiber( 0 ); if( !main_cor.m_fiber && GetLastError() == ERROR_ALREADY_FIBER ) { // conversion of current thread to fiber has failed, because // someone else already converted the main thread to a fiber // -> store current fiber main_cor.m_fiber = GetCurrentFiber(); } assert( main_cor.m_fiber != 0 ); # if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__ // initialize the current coroutine assert( curr_cor == 0 ); curr_cor = &main_cor; # endif } }
void FiberManager::WorkerMain(FiberManager* fiberMgr, unsigned threadIndex) { s_currentThread = int(threadIndex); auto& threadData = fiberMgr->m_threadData[threadIndex]; // initial set up #if defined(WINDOWS) threadData.m_mainFiber = ConvertThreadToFiber(nullptr); #elif defined(LINUX) #error linux version of FiberManager::InitThread not yet implemented #endif // main scheduling loop while (!fiberMgr->m_exitRequested.load(std::memory_order_relaxed)) { // TODO: this thread can sleep if there are no executing fibers and no // tasks available. Do a lazy check followed by a cv block here in those cases // and notify when executing list changes or tasks are pushed fiberMgr->ScheduleOneFiber(); } }