コード例 #1
0
ファイル: pthreads_win32.c プロジェクト: Ferada/sbcl
VOID CALLBACK Fiber_Function(LPVOID param)
{
  pthread_t self = (pthread_t) param;
  thread_or_fiber_function(param);
  {
    /* fiber_group is a main thread into which we are to call */
    pthread_t group = self->fiber_group;
    free(self);
    /* pthread_np_run_in_fiber (see below) normally switches back to
       caller. Nullify our identity, so it knows there is nothing to
       switch to, and continues running instead. */
    tls_impersonate(NULL);
    if (group) {
      /* Every running [pthread_create]d fiber runs in some thread
         that has its own pthread_self identity (that was created as
         thread and later converted to fiber). `group' field of
         running fiber always points to that other pthread.

         Now switch to our group ("current master fiber created as
         thread"), asking it to delete our (OS) fiber data with
         fiber_destructor. */
      pthread_np_run_in_fiber(group, fiber_destructor, GetCurrentFiber());
    }
    /* Within current pthread API we never end up here.

     BTW, if fibers are ever pooled, to avoid stack space reallocation
     etc, jumping to the beginning of Fiber_Function should be the
     thing to do here. */
    DeleteFiber(GetCurrentFiber()); /* Exits. See Thread_Function for
                                       explanation -- why not
                                       ExitThread. */
  }
}
コード例 #2
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不足"));
}
コード例 #3
0
ファイル: Coro.c プロジェクト: 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
}
コード例 #4
0
ファイル: TcpConnection.cpp プロジェクト: cryptobuks/forknote
std::size_t TcpConnection::write(const uint8_t* data, size_t size) {
  assert(dispatcher != nullptr);
  assert(writeContext == nullptr);
  if (stopped) {
    throw InterruptedException();
  }

  if (size == 0) {
    if (shutdown(connection, SD_SEND) != 0) {
      throw std::runtime_error("TcpConnection::write, shutdown failed, result=" + std::to_string(WSAGetLastError()));
    }

    return 0;
  }

  WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(const_cast<uint8_t*>(data))};
  TcpConnectionContext context;
  context.hEvent = NULL;
  if (WSASend(connection, &buf, 1, NULL, 0, &context, NULL) != 0) {
    int lastError = WSAGetLastError();
    if (lastError != WSA_IO_PENDING) {
      throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError));
    }
  }

  context.context = GetCurrentFiber();
  context.interrupted = false;
  writeContext = &context;
  dispatcher->dispatch();
  assert(context.context == GetCurrentFiber());
  assert(dispatcher != nullptr);
  assert(writeContext == &context);
  writeContext = nullptr;
  DWORD transferred;
  DWORD flags;
  if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) {
    int lastError = WSAGetLastError();
    if (lastError != ERROR_OPERATION_ABORTED) {
      throw std::runtime_error("TcpConnection::write, WSASend failed, result=" + std::to_string(lastError));
    }

    assert(context.interrupted);
    throw InterruptedException();
  }

  assert(transferred == size);
  assert(flags == 0);
  return transferred;
}
コード例 #5
0
ファイル: context_windows_fibers.hpp プロジェクト: 41i/hpx
      /*
       * 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;
        }
      }
コード例 #6
0
ファイル: coroutine.cpp プロジェクト: ennis/rift
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());
}
コード例 #7
0
ファイル: context_windows_fibers.hpp プロジェクト: 41i/hpx
    /*
     * Return true if current thread is a fiber.
     */
    inline bool is_fiber() {
#if _WIN32_WINNT >= 0x0600
      return IsThreadAFiber() ? true : false;
#else
      fiber_ptr current = GetCurrentFiber();
      return current != 0 && current != fiber_magic;
#endif
    }
コード例 #8
0
ファイル: FiberWin32.cpp プロジェクト: ixc-software/lucksi
        void Return()
        {
            ESS_ASSERT( GetCurrentFiber() == m_handle );

            ESS_ASSERT( m_fiberToReturn != 0);
            LPVOID ret = m_fiberToReturn;
            m_fiberToReturn = 0;
            SwitchToFiber(ret);
        }
コード例 #9
0
sc_cor_fiber::~sc_cor_fiber()
{
    if( m_fiber != 0 ) {
#     ifdef WIN32
      PVOID cur_fiber = GetCurrentFiber();
      if (m_fiber != cur_fiber)
#     endif
	DeleteFiber( m_fiber );
    }
}
コード例 #10
0
ファイル: concurrent.cpp プロジェクト: energyfive/sc-core
void ReentrantLock::unlock() 
{
    if (owner == GetCurrentFiber()) {
        if (holdCount != 0) {
            holdCount--;
        } else {
            SimpleLock::unlock();
        }
    }
}
コード例 #11
0
ファイル: FiberWin32.cpp プロジェクト: ixc-software/lucksi
 static void MainThreadInit()
 {            
     PVOID pData = GetCurrentFiber();
     if (pData == (void*)0x1E00)  // magic
     {
         LPVOID h = ConvertThreadToFiber( &MainFiberId );
         ESS_ASSERT(h != 0);
         ESS_ASSERT( GetFiberData() == &MainFiberId );
     }
 }
コード例 #12
0
ファイル: FiberWin32.cpp プロジェクト: ixc-software/lucksi
        void Run()
        {
            ESS_ASSERT(m_fiberToReturn == 0);

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

            SwitchToFiber(m_handle);
        }
コード例 #13
0
ファイル: TcpConnection.cpp プロジェクト: cryptobuks/forknote
size_t TcpConnection::read(uint8_t* data, size_t size) {
  assert(dispatcher != nullptr);
  assert(readContext == nullptr);
  if (stopped) {
    throw InterruptedException();
  }

  WSABUF buf{static_cast<ULONG>(size), reinterpret_cast<char*>(data)};
  DWORD flags = 0;
  TcpConnectionContext context;
  context.hEvent = NULL;
  if (WSARecv(connection, &buf, 1, NULL, &flags, &context, NULL) != 0) {
    int lastError = WSAGetLastError();
    if (lastError != WSA_IO_PENDING) {
      throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError));
    }
  }

  assert(flags == 0);
  context.context = GetCurrentFiber();
  context.interrupted = false;
  readContext = &context;
  dispatcher->dispatch();
  assert(context.context == GetCurrentFiber());
  assert(dispatcher != nullptr);
  assert(readContext == &context);
  readContext = nullptr;
  DWORD transferred;
  if (WSAGetOverlappedResult(connection, &context, &transferred, FALSE, &flags) != TRUE) {
    int lastError = WSAGetLastError();
    if (lastError != ERROR_OPERATION_ABORTED) {
      throw std::runtime_error("TcpConnection::read, WSARecv failed, result=" + std::to_string(lastError));
    }

    assert(context.interrupted);
    throw InterruptedException();
  }

  assert(transferred <= size);
  assert(flags == 0);
  return transferred;
}
コード例 #14
0
ファイル: realmain.c プロジェクト: NRauh/wordgrinder
void dpy_flushkeys(void)
{
	if (GetCurrentFiber() == uifiber)
	{
		while (numqueued)
		{
			currentkey = dequeue();
			SwitchToFiber(appfiber);
		}
	}
}
コード例 #15
0
ファイル: Dispatcher.cpp プロジェクト: inmoney/bytecoin
void Dispatcher::contextProcedure() {
  assert(GetCurrentThreadId() == threadId);
  for (;;) {
    assert(!spawningProcedures.empty());
    std::function<void()> procedure = std::move(spawningProcedures.front());
    spawningProcedures.pop();
    procedure();
    reusableContexts.push(GetCurrentFiber());
    dispatch();
  }
}
コード例 #16
0
ファイル: concurrent.cpp プロジェクト: energyfive/sc-core
void ReentrantLock::lock() 
{
    // Если текущий фибер уже владеет блокировкой, 
    // то увеличиваем счетчик, иначе ожидаем освобождения блокировки.
    if (owner == GetCurrentFiber()) {
        holdCount++;
    } else {
        SimpleLock::lock();
        initNewOwner();
    }
}
コード例 #17
0
ファイル: Dispatcher.cpp プロジェクト: inmoney/bytecoin
void Dispatcher::yield() {
  assert(GetCurrentThreadId() == threadId);
  for (;;) {
    LARGE_INTEGER frequency;
    LARGE_INTEGER ticks;
    QueryPerformanceCounter(&ticks);
    QueryPerformanceFrequency(&frequency);
    uint64_t currentTime = ticks.QuadPart / (frequency.QuadPart / 1000);
    auto timerContextPair = timers.begin();
    auto end = timers.end();
    while (timerContextPair != end && timerContextPair->first <= currentTime) {
      resumingContexts.push(timerContextPair->second);
      timerContextPair = timers.erase(timerContextPair);
    }

    OVERLAPPED_ENTRY entries[16];
    ULONG actual = 0;
    if (GetQueuedCompletionStatusEx(completionPort, entries, 16, &actual, 0, TRUE) == TRUE) {
      assert(actual > 0);
      for (ULONG i = 0; i < actual; ++i) {
        if (entries[i].lpOverlapped == reinterpret_cast<LPOVERLAPPED>(remoteSpawnOverlapped)) {
          EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection));
          assert(remoteNotificationSent);
          assert(!remoteSpawningProcedures.empty());
          do {
            spawn(std::move(remoteSpawningProcedures.front()));
            remoteSpawningProcedures.pop();
          } while (!remoteSpawningProcedures.empty());

          remoteNotificationSent = false;
          LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection));
          continue;
        }

        void* context = reinterpret_cast<DispatcherContext*>(entries[i].lpOverlapped)->context;
        resumingContexts.push(context);
      }
    } else {
      DWORD lastError = GetLastError();
      if (lastError == WAIT_TIMEOUT) {
        break;
      } else if (lastError != WAIT_IO_COMPLETION) {
        throw std::runtime_error("Dispatcher::dispatch, GetQueuedCompletionStatusEx failed, result=" + std::to_string(lastError));
      }
    }
  }

  if (!resumingContexts.empty()) {
    resumingContexts.push(GetCurrentFiber());
    dispatch();
  }
}
コード例 #18
0
ファイル: acid64.cpp プロジェクト: mwgoldsmith/sidplay2-libs
 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;
     }
 }
コード例 #19
0
ファイル: coro.c プロジェクト: AlwaysGeeky/nanogui
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);
}
コード例 #20
0
void TaskScheduler::WaitForCounter(std::shared_ptr<AtomicCounter> &counter, int value) {
	if (counter->load() == value) {
		return;
	}

	// Switch to a new Fiber
	m_fiberPool.wait_dequeue(tls_fiberToSwitchTo);

	tls_currentFiber = GetCurrentFiber();
	tls_waitingCounter = counter.get();
	tls_waitingValue = value;
	
	SwitchToFiber(m_counterWaitingFibers[tls_threadId]);
}
コード例 #21
0
Dispatcher::Dispatcher() {
  static_assert(sizeof(CRITICAL_SECTION) == sizeof(Dispatcher::criticalSection), "CRITICAL_SECTION size doesn't fit sizeof(Dispatcher::criticalSection)");
  BOOL result = InitializeCriticalSectionAndSpinCount(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection), 4000);
  assert(result != FALSE);
  std::string message;
  if (ConvertThreadToFiberEx(NULL, 0) == NULL) {
    message = "ConvertThreadToFiberEx failed, " + lastErrorMessage();
  } else {
    completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    if (completionPort == NULL) {
      message = "CreateIoCompletionPort failed, " + lastErrorMessage();
    } else {
      WSADATA wsaData;
      int wsaResult = WSAStartup(0x0202, &wsaData);
      if (wsaResult != 0) {
        message = "WSAStartup failed, " + errorMessage(wsaResult);
      } else {
        remoteNotificationSent = false;
        reinterpret_cast<LPOVERLAPPED>(remoteSpawnOverlapped)->hEvent = NULL;
        threadId = GetCurrentThreadId();

        mainContext.fiber = GetCurrentFiber();
        mainContext.interrupted = false;
        mainContext.group = &contextGroup;
        mainContext.groupPrev = nullptr;
        mainContext.groupNext = nullptr;
        mainContext.inExecutionQueue = false;
        contextGroup.firstContext = nullptr;
        contextGroup.lastContext = nullptr;
        contextGroup.firstWaiter = nullptr;
        contextGroup.lastWaiter = nullptr;
        currentContext = &mainContext;
        firstResumingContext = nullptr;
        firstReusableContext = nullptr;
        runningContextCount = 0;
        return;
      }

      BOOL result2 = CloseHandle(completionPort);
      assert(result2 == TRUE);
    }

    BOOL result2 = ConvertFiberToThread();
    assert(result == TRUE);
  }
  
  DeleteCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection));
  throw std::runtime_error("Dispatcher::Dispatcher, " + message);
}
コード例 #22
0
        void FiberManager::YieldFiber()
        {
            const auto fiber = GetCurrentFiber();
            ASSERT(fiber != nullptr);

            const auto threadIndex = fiber->m_threadIndex;
            ASSERT(threadIndex >= 0 && threadIndex < int(m_threadData.size()));
            auto&& threadData = m_threadData[threadIndex];

#if defined (WINDOWS)
            SwitchToFiber(threadData.m_mainFiber);
#else
            static_assert(false, "implement this function for this OS");
#endif
        }
コード例 #23
0
ファイル: Main.cpp プロジェクト: Alo81/scripthookvdotnet
void ScriptMainSetup()
{
	sGameReloaded = true;
	sMainFib = GetCurrentFiber();

	if (sScriptFib == nullptr)
	{
		// Create our own fiber for the common language runtime once
		sScriptFib = CreateFiber(0, reinterpret_cast<LPFIBER_START_ROUTINE>(&ScriptMainLoop), nullptr);
	}

	while (true)
	{
		// Yield execution
		scriptWait(0);

		// Switch to our own fiber and wait for it to switch back
		SwitchToFiber(sScriptFib);
	}
}
コード例 #24
0
        void FiberManager::YieldFiberToService(FiberService* service, void* requestData)
        {
            const auto fiber = GetCurrentFiber();
            ASSERT(fiber != nullptr);

            const auto threadIndex = fiber->m_threadIndex;
            ASSERT(threadIndex >= 0 && threadIndex < int(m_threadData.size()));
            auto&& threadData = m_threadData[threadIndex];

            // we set this before pushing the service fiber so it has all the data it needs to begin
            ASSERT(fiber->m_serviceData == nullptr);
            fiber->m_serviceData = requestData;
            service->PushServiceFiber(fiber);

#if defined (WINDOWS)
            SwitchToFiber(threadData.m_mainFiber);
#else
            static_assert(false, "implement this function for this OS");
#endif
        }
コード例 #25
0
ファイル: pthreads_win32.c プロジェクト: Ferada/sbcl
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;
}
コード例 #26
0
ファイル: pthreads_win32.c プロジェクト: Ferada/sbcl
/* Thread function for [pthread_create]d threads. Thread may become a
   fiber later, but (as stated above) it isn't supposed to be
   reattached to other system thread, even after it happens.
*/
DWORD WINAPI Thread_Function(LPVOID param)
{
  pthread_t self = (pthread_t) param;

  self->teb = NtCurrentTeb();
  thread_or_fiber_function(param);
  CloseHandle(self->handle);
  {
    void* fiber = self->fiber;
    free(self);
    if (fiber) {
      /* If thread was converted to fiber, deleting the fiber from
         itself exits the thread. There are some rumors on possible
         memory leaks if we just ExitThread or return here, hence the
         statement below. However, no memory leaks on bare ExitThread
         were observed yet. */
      DeleteFiber(GetCurrentFiber());
    }
  }
  return 0;
}
コード例 #27
0
ファイル: async_win.c プロジェクト: BlackOmega/openssl
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;
}
コード例 #28
0
VOID WINAPI LogMessage(PVOID pFlsValue)
{
   TCHAR szMsg[MAX_PATH];

   // Check if we are in a fiber because this function can be called 
   // outside a fiber execution
   if (IsThreadAFiber())
   {
      PVOID pFiberData = GetCurrentFiber();
      PCTSTR pszFlsValue = (PCTSTR)FlsGetValue(g_dwSlot);
      StringCchPrintf(szMsg, _countof(szMsg), TEXT("[0x%x - %s] %s\n"), 
         pFiberData,
         (pszFlsValue == NULL) ? TEXT("'Null value'") : (PCTSTR)pszFlsValue,
         (pFlsValue == NULL) ? TEXT("'Null value'") : (PCTSTR)pFlsValue);
   }
   else
   {
      StringCchCopy(szMsg, _countof(szMsg), TEXT("No more a fiber...\n"));
   }
   /* Sends a string to the debugger for display. */
   OutputDebugString(szMsg);
}
コード例 #29
0
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
    }
}
コード例 #30
0
ファイル: Coro.c プロジェクト: jamesrburgess/io
void Coro_StartWithArg(CallbackBlock *block)
{
#ifdef USE_FIBERS
	MEMORY_BASIC_INFORMATION meminfo;
	if (block->associatedCoro->fiber != GetCurrentFiber())
		abort();
	// Set the start of the stack for future comparaison. According to
	// http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx,
	// some part of the stack is reserved for running an handler if
	// the fiber exhaust its stack, but we have no way of retrieving
	// this information (SetThreadStackGuarantee() is not supported
	// on WindowsXP), so we have to assume that it is the default
	// 64kB.
	// Look at the descriptors of the meminfo structure, which is
	// conveniently located on the stack we are interested into.
	VirtualQuery(&meminfo, &meminfo, sizeof meminfo);
	block->associatedCoro->stack =
		(char*)meminfo.AllocationBase + 64 * 1024;
#endif
	(block->func)(block->context);
	printf("Scheduler error: returned from coro start function\n");
	exit(-1);
}