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不足"));
}
Esempio n. 2
0
/*
 * @implemented
 */
LPVOID
WINAPI
ConvertThreadToFiber(LPVOID lpParameter)
{
    /* Call the newer function */
    return ConvertThreadToFiberEx(lpParameter, 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);
}
Esempio n. 4
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, result=" + std::to_string(GetLastError());
  } else {
    threadHandle = OpenThread(THREAD_SET_CONTEXT, FALSE, GetCurrentThreadId());
    if (threadHandle == NULL) {
      message = "OpenThread failed, result=" + std::to_string(GetLastError());
    } else {
      completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
      if (completionPort == NULL) {
        message = "CreateIoCompletionPort failed, result=" + std::to_string(GetLastError());
      } else {
        WSADATA wsaData;
        int wsaResult = WSAStartup(0x0202, &wsaData);
        if (wsaResult != 0) {
          message = "WSAStartup failed, result=" + std::to_string(wsaResult);
        } else {
          contextCount = 0;
          remoteNotificationSent = false;
          reinterpret_cast<LPOVERLAPPED>(remoteSpawnOverlapped)->hEvent = NULL;
          threadId = GetCurrentThreadId();
          return;
        }

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

      BOOL result = CloseHandle(threadHandle);
      assert(result == TRUE);
    }

    BOOL result = ConvertFiberToThread();
    assert(result == TRUE);
  }
  
  DeleteCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(criticalSection));
  throw std::runtime_error("Dispatcher::Dispatcher, " + message);
}
Esempio n. 5
0
void TaskScheduler::Initialize(GlobalArgs *globalArgs) {
	for (uint i = 0; i < FIBER_POOL_SIZE; ++i) {
		m_fiberPool.enqueue(CreateFiberEx(524288, 0, FIBER_FLAG_FLOAT_SWITCH, FiberStart, globalArgs));
	}

	SYSTEM_INFO sysinfo;
	GetSystemInfo(&sysinfo);

	// Create an additional thread for each logical processor
	m_numThreads = sysinfo.dwNumberOfProcessors;
	m_threads = new HANDLE[m_numThreads];
	m_fiberSwitchingFibers = new void *[m_numThreads];
	m_counterWaitingFibers = new void *[m_numThreads];


	// Create a switching fiber for each thread
	for (uint i = 0; i < m_numThreads; ++i) {
		m_fiberSwitchingFibers[i] = CreateFiberEx(32768, 0, FIBER_FLAG_FLOAT_SWITCH, FiberSwitchStart, &globalArgs->TaskScheduler);
		m_counterWaitingFibers[i] = CreateFiberEx(32768, 0, FIBER_FLAG_FLOAT_SWITCH, CounterWaitStart, &globalArgs->TaskScheduler);
	}

	// Set the affinity for the current thread and convert it to a fiber
	SetThreadAffinityMask(GetCurrentThread(), 1);
	ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH);
	m_threads[0] = GetCurrentThread();
	tls_threadId = 0;
	
	// Create the remaining threads
	for (DWORD i = 1; i < m_numThreads; ++i) {
		ThreadStartArgs *threadArgs = new ThreadStartArgs();
		threadArgs->globalArgs = globalArgs;
		threadArgs->threadId = i;

		HANDLE threadHandle = (HANDLE)_beginthreadex(nullptr, 524288, ThreadStart, threadArgs, CREATE_SUSPENDED, nullptr);
		m_threads[i] = threadHandle;

		DWORD_PTR mask = 1 << i;
		SetThreadAffinityMask(threadHandle, mask);
		ResumeThread(threadHandle);
	}
}
Esempio n. 6
0
void Ink_initCoroutine()
{
	ConvertThreadToFiberEx(NULL, FIBER_FLAG_FLOAT_SWITCH);
	return;
}
Esempio n. 7
0
int 
clemuGPU :: scheduleNextJob(void)
{
int ret = CL_EMU_SUCCESS;
// TO DO : SELECT JOB
// SELECT SE, SIMD
clemuKernelJob *nextJob = m_job[0];
int cur_gbl_tid;
clemuGPU* dev = (clemuGPU*)(nextJob->GetDev());

   nextJob->m_next_active_group = 0;
   nextJob->m_fiber.m_FIBER_id = ConvertThreadToFiberEx(nextJob,FIBER_FLAG_FLOAT_SWITCH);
   nextJob->m_fiber.m_FLS_index = 0;

// TO DO: NBR GROUPS > SIMDS
// run
   for(int j = 0, grp_id = 0, wf_id = 0; j < nextJob->m_nbr_grpDim[1]; j++)
   {
      for(int i = 0; i < nextJob->m_nbr_grpDim[0]; i++, grp_id++, wf_id += nextJob->m_nbr_wavefronts)
	  {
int active_grp = nextJob->m_next_active_group;
// activate

		  if ( !nextJob->m_groups[active_grp].m_fiber.m_FIBER_id )
		  {
		       nextJob->m_groups[active_grp].m_fiber.m_FIBER_id = 
			               CreateFiberEx( CLEMU_STACKCOMMITSIZE,
                                           CLEMU_STACKRESERVESIZE,
										   FIBER_FLAG_FLOAT_SWITCH,
										   clemu_groupthread_proc,
										   &nextJob->m_groups[active_grp]);

			   assert(nextJob->m_groups[active_grp].m_fiber.m_FIBER_id);
		       nextJob->m_groups[active_grp].m_fiber.m_FLS_index = 0;
		  }

		  if ( !nextJob->m_groups[active_grp].m_td_fibers )
		  {
	           nextJob->m_groups[active_grp].m_td_fibers = new CL_EMU_FIBER[nextJob->GetNbrInstances()];
		       assert(nextJob->m_groups[active_grp].m_td_fibers);
        	   memset(nextJob->m_groups[active_grp].m_td_fibers, 0, sizeof(CL_EMU_FIBER) * nextJob->GetNbrInstances()); 
		  }

		  for(int l = 0, tid = 0; l < nextJob->GetNbrWavefronts(); l++)
		  {
			  int wf_sz = nextJob->GetRealWFSz(l);
			  for(int m = 0; m < wf_sz; m++, tid++)
			  {
				  if ( !nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id )
				  {
                     nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id = 
						    CreateFiberEx( CLEMU_STACKCOMMITSIZE,
                                           CLEMU_STACKRESERVESIZE,
										   FIBER_FLAG_FLOAT_SWITCH,
						                   clemu_wavefrontthread_proc,
										   &nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m]);

					 assert(nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id);

				     nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FLS_index = 0; //FlsAlloc(0);
				     nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_group_ptr = &nextJob->m_groups[active_grp];
				  }

			  }
		  }



          nextJob->m_groups[active_grp].m_parent = nextJob;
		  nextJob->m_groups[active_grp].m_grpCoord[0] = i;
		  nextJob->m_groups[active_grp].m_grpCoord[1] = j;
		  nextJob->m_groups[active_grp].m_grpCoord[2] = 0;
		  nextJob->m_groups[active_grp].m_group_id = grp_id;
		  nextJob->m_groups[active_grp].m_se_id = 0;
		  nextJob->m_groups[active_grp].m_simd_id = active_grp % dev->GetNbrSIMD();
	      nextJob->m_groups[active_grp].m_first_hwwavefront = wf_id;

		  cur_gbl_tid = grp_id * nextJob->m_actual_nbr_instances;
          nextJob->m_groups[active_grp].m_kernel = nextJob->GetKernel();
		  nextJob->m_groups[active_grp].m_endof_group = 0;
// local memory setup
// EXPLANATION:
// The size comes either from invokation (argument) or from teh kernel declaration.
// if it comes from declaration for teh first group there will be 0 sz which is max size.
// second group will det the correect size and will be separated from teh first group
int local_mem_sz = (nextJob->m_localmem_sz > clemuGetCompiledKernelMemSz(nextJob->m_groups[active_grp].m_kernel)) ? nextJob->m_localmem_sz : clemuGetCompiledKernelMemSz(nextJob->m_groups[active_grp].m_kernel);
		  nextJob->m_groups[active_grp].m_localmem_sz = local_mem_sz;
		  nextJob->m_groups[active_grp].m_localmem_ptr = (unsigned char*)dev->AssignLclMem(nextJob->m_groups[active_grp].m_simd_id,active_grp,local_mem_sz); 
		  if ( nextJob->m_groups[active_grp].m_nmb_arg > 0 )
          {
		       for( int l = 0; l < nextJob->m_groups[active_grp].m_nmb_arg; l++)
		       {
		           if ( (nextJob->m_groups[active_grp].m_args[l].m_flags & CL_ARG_LCL_MEM_SZ) == CL_ARG_LCL_MEM_SZ )
		           {
					   nextJob->m_groups[active_grp].m_args[l].m_flags |= CL_ARG_LDS_PTR;
					   nextJob->m_groups[active_grp].m_args[l].m_arg.parg = nextJob->m_groups[active_grp].m_localmem_ptr;
					   break;
		           }
		       }
          }

//		  nextJob->m_groups[grp_id].m_wf_fibers = new CL_EMU_FIBER[nextJob->m_nbr_wavefronts];
//		  assert(nextJob->m_groups[grp_id].m_wf_fibers);
		  if ( !nextJob->m_groups[active_grp].m_td_fibers )
		  {
	           nextJob->m_groups[active_grp].m_td_fibers = new CL_EMU_FIBER[nextJob->m_actual_nbr_instances];
		       assert(nextJob->m_groups[active_grp].m_td_fibers);
		  }


		  for(int l = 0, tid = 0; l < nextJob->m_nbr_wavefronts; l++)
		  {
			  int wf_sz = nextJob->GetRealWFSz(l);
			  for(int m = 0; m < wf_sz; m++, tid++)
			  {
                  nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_grp_tid = l * wf_sz + m;
                  nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_gbl_tid = cur_gbl_tid + nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_grp_tid;
                  nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_wfid = l;
                  nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_wf_tid = m;
			  }
		  }

// schedule group
          nextJob->m_curgroup = active_grp;

		  SwitchToFiber(nextJob->m_groups[active_grp].m_fiber.m_FIBER_id);
// free

		  if ( nextJob->m_groups[active_grp].m_td_fibers )
		  {
		       for(int l = 0, tid = 0; l < nextJob->GetNbrWavefronts(); l++)
		       {
			  int wf_sz = nextJob->GetRealWFSz(l);
			       for(int m = 0; m < wf_sz; m++, tid++)
			       {
				       if ( nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id )
				       {
                           DeleteFiber(nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id);
					       nextJob->m_groups[active_grp].m_td_fibers[l*wf_sz + m].m_FIBER_id = 0;
				        }

			        }
		       }
	           delete [] nextJob->m_groups[active_grp].m_td_fibers;
		       nextJob->m_groups[active_grp].m_td_fibers = 0;
		  }
		  if ( nextJob->m_groups[active_grp].m_fiber.m_FIBER_id )
		  {
		      DeleteFiber(nextJob->m_groups[active_grp].m_fiber.m_FIBER_id);
		      nextJob->m_groups[active_grp].m_fiber.m_FIBER_id = 0;
		  }

          nextJob->m_next_active_group = (active_grp + 1) %  nextJob->m_nbr_active_group;
	  }
   }

   nextJob->FreeJob();

   ConvertFiberToThread();
   nextJob->m_fiber.m_FIBER_id = 0;

   return(ret);

}
Esempio n. 8
0
File: Fiber.cpp Progetto: Rn86/Boron
		Impl(FiberUID uid, FiberFlags flags)
			: Impl(uid, ConvertThreadToFiberEx(this, MakeFlags(flags)))
		{
		}