Example #1
0
      /*
       * 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;
        }
      }
Example #2
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;
}
Example #3
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);
      }
   }
}
Example #4
0
struct ff_arch_fiber *ff_arch_fiber_initialize()
{
	main_fiber.handle = ConvertThreadToFiber((LPVOID) NULL);
	ff_assert(main_fiber.handle != NULL);

	return &main_fiber;
}
Example #5
0
	INT32 CoInit()
	{
		void * pFiberContext = ConvertThreadToFiber(NULL);
		MsgAssert_ReF1(pFiberContext, "Create fiber error.");

		g_FiberContext.set(pFiberContext);
		return 0;
	}
Example #6
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;
}
Example #7
0
TContMachineContext::TContMachineContext()
    : Fiber_(ConvertThreadToFiber(this))
    , MainFiber_(true)
{
    if (!Fiber_) {
        ythrow yexception() << "fiber error";
    }
}
Example #8
0
Coroutine *qemu_coroutine_self(void)
{
    if (!current) {
        current = &leader.base;
        leader.fiber = ConvertThreadToFiber(NULL);
    }
    return current;
}
Example #9
0
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());
}
Example #10
0
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)");
    }
}
Example #11
0
/*--------------------------------------------------------------------------*/
void
mtarch_init(void)
{
#ifdef __CYGWIN__

  main_fiber = ConvertThreadToFiber(NULL);

#endif /* __CYGWIN__ */
}
Example #12
0
/*--------------------------------------------------------------------------*/
void
mtarch_init(void)
{
#if defined(_WIN32) || defined(__CYGWIN__)

  main_fiber = ConvertThreadToFiber(NULL);

#endif /* _WIN32 || __CYGWIN__ */
}
Example #13
0
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;
}
Example #14
0
 static void MainThreadInit()
 {            
     PVOID pData = GetCurrentFiber();
     if (pData == (void*)0x1E00)  // magic
     {
         LPVOID h = ConvertThreadToFiber( &MainFiberId );
         ESS_ASSERT(h != 0);
         ESS_ASSERT( GetFiberData() == &MainFiberId );
     }
 }
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
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;
     }
 }
Example #19
0
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);
}
Example #20
0
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;
}
Example #21
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;
}
Example #22
0
File: Coro.c Project: doublec/io
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
}
Example #23
0
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;
}
Example #24
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;
        }
Example #25
0
// 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);
        }
    }
}
Example #26
0
	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();
	}
Example #27
0
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;
}
Example #28
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
    }
}
Example #30
0
        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();
            }

        }