예제 #1
0
static VOID 
__stdcall clemu_groupthread_proc ( LPVOID lpParameter )
{
clemuKernelGroup *group = (clemuKernelGroup *)lpParameter;
clemuKernelJob *job = (clemuKernelJob *)(group->GetParent());
int curwfid = 0;
//	while(true)
	{
       group->SetCurWF(curwfid);
// PROCESS GROUP HERE
       while(!group->IsEndof() || (job->GetNbrWavefronts() > curwfid) )
       {
            curwfid = group->GetCurWF();
// switch to the first thread of a wavefront
            SwitchToFiber(group->GetTFiber(curwfid, 0)->m_FIBER_id);

// select new wf
			curwfid = (group->IsEndof()) ? (curwfid + 1) : (curwfid + 1) % job->GetNbrWavefronts(); 
            group->SetCurWF(curwfid);

        }

// back to scheduler
        SwitchToFiber(job->GetFiber()->m_FIBER_id);
	}
   

}
예제 #2
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;
        }
      }
예제 #3
0
FiberPool_::coro_pull_interface* FiberPool_::getFiber(size_t size, void** sp, coro_handler h, void* param /*= NULL*/)
{
	assert(size && size % 4096 == 0 && size <= 1024 * 1024);
	void* currentFiber = NULL;
#if _WIN32_WINNT >= 0x0600
	if (IsThreadAFiber())
	{
		currentFiber = GetCurrentFiber();
	}
	else
	{
		currentFiber = ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH);
	}
#else//#elif _MSC_VER >= 0x0501
	currentFiber = ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH);
	if (!currentFiber)
	{
		currentFiber = GetCurrentFiber();
	}
#endif
	{
		fiber_pool_pck& pool = s_fiberPool._fiberPool[size / 4096 - 1];
		pool._mutex.lock();
		if (!pool._pool.empty())
		{
			coro_pull_interface* oldFiber = pool._pool.back();
			pool._pool.pop_back();
			pool._mutex.unlock();
			oldFiber->_fiber._pushHandle = currentFiber;
			oldFiber->_fiber._currentHandler = h;
			oldFiber->_fiber._fiberHandle->_param = param;
			oldFiber->_fiber._tick = 0;
			*sp = oldFiber->_fiber._fiberHandle->_stackTop;
			SwitchToFiber(oldFiber->_fiber._fiberHandle);
			return oldFiber;
		}
		pool._mutex.unlock();
	}
	s_fiberPool._stackCount++;
	s_fiberPool._stackTotalSize += size;
	coro_pull_interface* newFiber = new coro_pull_interface;
#ifdef _WIN64
	newFiber->_fiber._fiberHandle = (FiberStruct_*)CreateFiberEx(size, 64 * 1024, FIBER_FLAG_FLOAT_SWITCH, FiberPool_::fiberHandler, newFiber);
#else
	newFiber->_fiber._fiberHandle = (FiberStruct_*)CreateFiberEx(size, 0, FIBER_FLAG_FLOAT_SWITCH, FiberPool_::fiberHandler, newFiber);
#endif
	if (newFiber->_fiber._fiberHandle)
	{
		newFiber->_fiber._pushHandle = currentFiber;
		newFiber->_fiber._currentHandler = h;
		newFiber->_fiber._fiberHandle->_param = param;
		newFiber->_fiber._tick = 0;
		*sp = newFiber->_fiber._fiberHandle->_stackTop;
		SwitchToFiber(newFiber->_fiber._fiberHandle);
		return newFiber;
	}
	delete newFiber;
	throw std::shared_ptr<string>(new string("Fiber不足"));
}
예제 #4
0
VOID __stdcall Fiber2( LPVOID lpParameter )
{
    buffer[i++] = '2';
    while( i < sizeof(buffer) - 1 )
    {
        buffer[i++] = 'a';
        SwitchToFiber( g_pFibers[FIBER1] );
    }

    SwitchToFiber( g_pFibers[FIBER_PRIMARY] );
}
예제 #5
0
파일: Fiber.cpp 프로젝트: yorung/MySnippets
VOID WINAPI FiberA(DWORD)
{
	for (;;) {
		puts("A");
		SwitchToFiber(mainFiber);
		puts("B");
		SwitchToFiber(mainFiber);
		puts("C");
		SwitchToFiber(mainFiber);
	}
}
예제 #6
0
파일: Fiber.cpp 프로젝트: yorung/MySnippets
VOID WINAPI FiberB(DWORD)
{
	for (;;) {
		puts("1");
		SwitchToFiber(mainFiber);
		puts("2");
		SwitchToFiber(mainFiber);
		puts("3");
		SwitchToFiber(mainFiber);
	}
}
예제 #7
0
파일: Fiber.cpp 프로젝트: yorung/MySnippets
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;
}
예제 #8
0
void WINAPI FiberFunc(PVOID pvParam) {

   PFIBERINFO pFiberInfo = (PFIBERINFO) pvParam;
   
   /* Stores a value in the calling fiber's fiber local storage (FLS) slot 
    * for the specified FLS index. 
	* Each fiber has its own slot for each FLS index. */
   FlsSetValue(g_dwSlot, TEXT("Computation"));

   LogMessage(TEXT("entering computation..."));

   // Update the window showing which fiber is executing.
   SetDlgItemText(pFiberInfo->hwnd, IDC_FIBER, TEXT("Recalculation"));

   // Get the current count in the EDIT control.
   int nCount = GetDlgItemInt(pFiberInfo->hwnd, IDC_COUNT, NULL, FALSE);
   
   // Count from 0 to nCount, updating the STATIC control.
   for (int x = 0; x <= nCount; x++) {

      // UI events have higher priority than counting.
      // If there are any UI events, handle them ASAP.
      /* Retrieves the type of messages found in the calling thread's message queue. */
      if (HIWORD(GetQueueStatus(QS_ALLEVENTS)) != 0) {

         // The UI fiber has something to do; temporarily
         // pause counting and handle the UI events.
         SwitchToFiber(pFiberInfo->pFiberUI);

         // The UI has no more events; continue counting.
         SetDlgItemText(pFiberInfo->hwnd, IDC_FIBER, TEXT("Recalculation"));
      }

      // Update the STATIC control with the most recent count.
      SetDlgItemInt(pFiberInfo->hwnd, IDC_ANSWER, x, FALSE);

      // Sleep for a while to exaggerate the effect; remove 
      // the call to Sleep in production code.
      Sleep(200);
   }

   // Indicate that counting is complete.
   pFiberInfo->bps = BPS_DONE;

   // Reschedule the UI thread. When the UI thread is running
   // and has no events to process, the thread is put to sleep.
   // NOTE: If we just allow the fiber function to return,
   // the thread and the UI fiber die -- we don't want this!
   SwitchToFiber(pFiberInfo->pFiberUI);
}
예제 #9
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);
      }
   }
}
예제 #10
0
// Return to the interrupted thread
void
Processor::finishInterrupt()
{
    auto core = tCurrentCore;
    auto fiber = core->interruptedFiber;

    core->currentFiber = fiber;
    core->interruptedFiber = nullptr;
    gLog->trace("Exit interrupt core {}", core->id);

    if (!fiber) {
        SwitchToFiber(core->primaryFiber);
    } else {
        SwitchToFiber(fiber->handle);
    }
}
예제 #11
0
파일: coroutine.cpp 프로젝트: ennis/rift
	static void yield(YieldOperation &&yieldOperation)
	{
		Coroutine::Impl *pImpl = (Coroutine::Impl*)GetFiberData();
		pImpl->yieldOperation = &yieldOperation;
		assert(pImpl != nullptr);
		SwitchToFiber(pImpl->pReturnFiber);
	}
예제 #12
0
파일: coroutine.cpp 프로젝트: ennis/rift
	static void coroutineEntry()
	{
		Coroutine::Impl *pImpl = (Coroutine::Impl*)GetFiberData();
		pImpl->entry();
		pImpl->status = Coroutine::Status::Terminated;
		SwitchToFiber(pImpl->pReturnFiber);
	}
예제 #13
0
 void Fiber::Continue()
 {
     if (m_fiber)
     {
         SwitchToFiber(m_fiber);
     }
 }
예제 #14
0
    void do_update_logic(WPARAM wParam, LPARAM lParam) {
        Impl::SCRIPT_END_HANDLER_LIST*	end_handlers	= reinterpret_cast<Impl::SCRIPT_END_HANDLER_LIST*>(lParam);
        {
            SCRIPT_LIST::iterator	it		= scripts_.begin();
            for(; it != scripts_.end(); ++it) {
                FiberContextImpl*	pScript = static_cast<FiberContextImpl*>(*it);
                if(pScript->is_running()) {
                    pScript->timestamp_	= timestamp_;
                    SwitchToFiber(pScript->fiber_);
                }
            }
        }

        {
            SCRIPT_LIST::iterator	it		= scripts_.begin();
            for(; it != scripts_.end(); ) {
                FiberContextImpl*	pScript = static_cast<FiberContextImpl*>(*it);
                if(!pScript->is_running() && (NULL != end_handlers)) {
                    if(pScript->callbacker_) {
                        FiberScriptEndHandler handler;
                        handler.id				= pScript->id_;
                        handler.param			= pScript->param_;
                        handler.handler			= pScript->callbacker_;
                        end_handlers->push_back(handler);
                    }

                    DeleteFiber(pScript->fiber_);
                    delete *it;
                    it = scripts_.erase(it);
                } else {
                    ++it;
                }
            }
        }
    }
예제 #15
0
// Sleep the interrupt thread until the first interrupt happens
void
Processor::waitFirstInterrupt()
{
    auto core = tCurrentCore;
    auto fiber = core->currentFiber;
    core->interruptHandlerFiber = fiber;
    SwitchToFiber(core->primaryFiber);
}
예제 #16
0
void __stdcall TaskScheduler::FiberSwitchStart(void *arg) {
	TaskScheduler *taskScheduler = (TaskScheduler *)arg;

	while (true) {
		taskScheduler->m_fiberPool.enqueue(tls_currentFiber);
		SwitchToFiber(tls_fiberToSwitchTo);
	}
}
예제 #17
0
파일: fiber.cpp 프로젝트: rod-lin/ink
void InkCoro_Scheduler::wrapper(LPVOID arg)
{
	InkCoro_Scheduler_wrapper_arg *tmp = (InkCoro_Scheduler_wrapper_arg *)arg;
	tmp->co->func(tmp->co->arg);
	tmp->sched->destroy(tmp->co);
	SwitchToFiber(tmp->sched->main_fib);
	return;
}
예제 #18
0
static void stop (Acid64 &inst)
{
    inst.engine->stop ();
    SafeThreadToFibre convert(inst.mainFiber);
    while (inst.engine->state() != sid2_stopped)
        SwitchToFiber (inst.engineFiber);
    inst.cycleCorrection = 0;
}
예제 #19
0
void
Processor::reschedule(bool hasSchedulerLock, bool yield)
{
    std::unique_lock<std::mutex> lock { mMutex };
    auto core = tCurrentCore;

    if (!core) {
        // Ran from host thread
        return;
    }

    auto fiber = core->currentFiber;
    auto thread = fiber->thread;
    auto next = peekNextFiberNoLock(core->id);

    // Priority is 0 = highest, 31 = lowest
    if (thread->suspendCounter <= 0 && thread->state == OSThreadState::Running) {
        if (!next) {
            // There is no thread to reschedule to
            return;
        }

        if (yield) {
            // Yield will transfer control to threads with equal or better priority
            if (thread->basePriority < next->thread->basePriority) {
                return;
            }
        } else {
            // Only reschedule to more important threads
            if (thread->basePriority <= next->thread->basePriority) {
                return;
            }
        }
    }

    // Change state to ready, only if this thread is running
    if (fiber->thread->state == OSThreadState::Running) {
        fiber->thread->state = OSThreadState::Ready;
    }

    // Add this fiber to queue
    queueNoLock(fiber);

    if (hasSchedulerLock) {
        OSUnlockScheduler();
    }

    gLog->trace("Core {} leave thread {}", core->id, fiber->thread->id);

    // Return to main scheduler fiber
    lock.unlock();
    SwitchToFiber(core->primaryFiber);

    // Reacquire scheduler lock if needed
    if (hasSchedulerLock) {
        OSLockScheduler();
    }
}
예제 #20
0
void
Processor::exit()
{
   // Return to parent fiber
   auto core = tCurrentCore;
   auto fiber = tCurrentCore->currentFiber;
   gLog->trace("Core {} exit thread {}", core->id, fiber->thread->id);
   SwitchToFiber(fiber->parentFiber);
}
예제 #21
0
        void Return()
        {
            ESS_ASSERT( GetCurrentFiber() == m_handle );

            ESS_ASSERT( m_fiberToReturn != 0);
            LPVOID ret = m_fiberToReturn;
            m_fiberToReturn = 0;
            SwitchToFiber(ret);
        }
예제 #22
0
static void runNewFiber()
{
	Fiber* fiber = g_pFiberPool[InterlockedDecrement(&g_fiberPoolHead) + 1];
	fiber->status = RUNNING;

	Thread* thread = TlsGetValue(g_threadData);
	thread->pCurrentFiber = fiber;
	SwitchToFiber(fiber->fiber);
}
예제 #23
0
파일: coroutine.c 프로젝트: Strongc/EffiLib
void coroutine_yield(struct schedule * S) 
{
    int id = S->running;
    struct coroutine* C;
    assert(id >= 0);
    C = S->co[id];
    C->status = COROUTINE_SUSPEND;
    S->running = -1;
    SwitchToFiber(S->main);
}
예제 #24
0
        void Run()
        {
            ESS_ASSERT(m_fiberToReturn == 0);

            m_fiberToReturn = GetCurrentFiber();
            ESS_ASSERT(m_fiberToReturn != 0);
            ESS_ASSERT(m_fiberToReturn != m_handle);

            SwitchToFiber(m_handle);
        }
예제 #25
0
void Dispatcher::contextProcedure() {
  assert(GetCurrentThreadId() == threadId);
  assert(firstReusableContext == nullptr);
  NativeContext context;
  context.interrupted = false;
  context.next = nullptr;
  context.inExecutionQueue = false;
  firstReusableContext = &context;
  SwitchToFiber(currentContext->fiber);
  for (;;) {
    ++runningContextCount;
    try {
      context.procedure();
    } catch (...) {
    }

    if (context.group != nullptr) {
      if (context.groupPrev != nullptr) {
        assert(context.groupPrev->groupNext == &context);
        context.groupPrev->groupNext = context.groupNext;
        if (context.groupNext != nullptr) {
          assert(context.groupNext->groupPrev == &context);
          context.groupNext->groupPrev = context.groupPrev;
        } else {
          assert(context.group->lastContext == &context);
          context.group->lastContext = context.groupPrev;
        }
      } else {
        assert(context.group->firstContext == &context);
        context.group->firstContext = context.groupNext;
        if (context.groupNext != nullptr) {
          assert(context.groupNext->groupPrev == &context);
          context.groupNext->groupPrev = nullptr;
        } else {
          assert(context.group->lastContext == &context);
          if (context.group->firstWaiter != nullptr) {
            if (firstResumingContext != nullptr) {
              assert(lastResumingContext->next == nullptr);
              lastResumingContext->next = context.group->firstWaiter;
            } else {
              firstResumingContext = context.group->firstWaiter;
            }

            lastResumingContext = context.group->lastWaiter;
            context.group->firstWaiter = nullptr;
          }
        }
      }

      pushReusableContext(context);
    }

    dispatch();
  }
}
예제 #26
0
/*
 * implementation for context_switch
 */
void context_switch(sc_context *  pContext) {
 
  assert(pContext != NULL);

  if (pContext->pFiber != NULL && !completed(pContext)) {
    if (current_context != NULL) if (!completed(current_context)) current_context->state = FS_DELAYED;
    current_context = pContext;
    SwitchToFiber(pContext->pFiber);
  }
  return;
}
예제 #27
0
void __stdcall TaskScheduler::CounterWaitStart(void *arg) {
	TaskScheduler *taskScheduler = (TaskScheduler *)arg;

	while (true) {
		EnterCriticalSection(&taskScheduler->m_waitingTaskLock);
		taskScheduler->m_waitingTasks.emplace_back(tls_currentFiber, tls_waitingCounter, tls_waitingValue);
		LeaveCriticalSection(&taskScheduler->m_waitingTaskLock);

		SwitchToFiber(tls_fiberToSwitchTo);
	}
}
예제 #28
0
void dpy_flushkeys(void)
{
	if (GetCurrentFiber() == uifiber)
	{
		while (numqueued)
		{
			currentkey = dequeue();
			SwitchToFiber(appfiber);
		}
	}
}
예제 #29
0
	void rawCorSwitchToFiber(void *fiber)
	{
#if defined(CORHOST)
		DWORD *cookie;
		corhost->SwitchOutLogicalThreadState(&cookie);
#endif
		SwitchToFiber(fiber);
#if defined(CORHOST)
		corhost->SwitchInLogicalThreadState(cookie);
#endif
	}
void
sc_cor_pkg_fiber::abort( sc_cor* next_cor )
{
    sc_cor_fiber* new_cor = SCAST<sc_cor_fiber*>( next_cor );
#   if defined(__GNUC__) && __USING_SJLJ_EXCEPTIONS__
        // Switch SJLJ exception handling function contexts
        _Unwind_SjLj_Register(&curr_cor->m_eh);
        _Unwind_SjLj_Unregister(&new_cor->m_eh);
        curr_cor = new_cor;
#   endif
    SwitchToFiber( new_cor->m_fiber );
}