コード例 #1
0
ファイル: brushbsp.c プロジェクト: JackalFrost/RTCW-WSGF
//get the first node from the front of the node list
node_t *NextNodeFromList( void ) {
	node_t *node;

	ThreadLock();
	numwaiting++;
	if ( !firstnode ) {
		if ( numwaiting >= GetNumThreads() ) {
			ThreadSemaphoreIncrease( GetNumThreads() );
		}
	} //end if
	ThreadUnlock();

	ThreadSemaphoreWait();

	ThreadLock();

	numwaiting--;

	node = firstnode;
	if ( firstnode ) {
		firstnode = firstnode->next;
		nodelistsize--;
	} //end if
	if ( !firstnode ) {
		lastnode = NULL;
	}

	ThreadUnlock();

	return node;
} //end of the function NextNodeFromList
コード例 #2
0
ファイル: ThreadPool.cpp プロジェクト: velteyn/spring
void SetThreadCount(int num)
{
	int curThreads = GetNumThreads();

	if (curThreads < num) {
#ifndef UNITSYNC
		if (hasOGLthreads) {
			try {
				for (int i = curThreads; i<num; ++i) {
					thread_group.push_back(new COffscreenGLThread(boost::bind(&WorkerLoop, i)));
				}
			} catch (const opengl_error& gle) {
				// shared gl context creation failed :<
				SetThreadCount(0);
				hasOGLthreads = false;
				curThreads = GetNumThreads();
			}
		}
#endif
		if (!hasOGLthreads) {
			for (int i = curThreads; i<num; ++i) {
				thread_group.push_back(new boost::thread(boost::bind(&WorkerLoop, i)));
			}
		}
	} else {
		for (int i = curThreads; i>num && i>1; --i) {
			assert(!thread_group.empty());

			auto taskgroup = std::make_shared<ParallelTaskGroup<const std::function<void()>>>();
			taskgroup->enqueue_unique(GetNumThreads() - 1, []{ exitThread = true; });
			ThreadPool::PushTaskGroup(taskgroup);
#ifndef UNITSYNC
			if (hasOGLthreads) {
				auto th = reinterpret_cast<COffscreenGLThread*>(thread_group.back());
				th->join();
				delete th;
			} else
#endif
			{
				auto th = reinterpret_cast<boost::thread*>(thread_group.back());
				th->join();
				delete th;
			}
			thread_group.pop_back();
		}
		if (num == 0) assert(thread_group.empty());
	}
}
コード例 #3
0
	void VulkanRenderer::OutputLog(std::ostream & fout)
	{
		fout << GetName() << "\n[" << GetNumVertices() << " vertices] [" << GetNumTriangles() << " triangles] [" << GetNumObjects() << " objects]" << std::endl;
		fout << "Threads: " << GetNumThreads() << std::endl;

		if(mUseInstancing)
			fout << "Pipeline: " << "Instancing" << std::endl;
		else if (mUseStaticCommandBuffer)
			fout << "Pipeline: " << "Static command buffers" << std::endl;
		else
			fout << "Pipeline: " << "Basic" << std::endl;
	}
コード例 #4
0
ファイル: hvl.cpp プロジェクト: echmet/HVL_MT
/*
 * @brief Divides the HVL calculation between all available CPUs and waits for the calculation to finish
 *
 * @param[in,out] pv Double pointer to the HVLValues that are to be returned
 * @param[in] ctx Calculation context
 * @param[in] from Value of X to calculate from
 * @param[in] to Value of X to calculate to
 * @param[in] step Difference between two consecutive values of X
 * @param[in] a0 HVL a0 parameter
 * @param[in] a1 HVL a1 parameter
 * @param[in] a2 HVL a2 parameter
 * @param[in] a3 HVL a3 parameter
 *
 * @return True on success, false on failure
 */
bool LaunchWorkersAndWait(HVL_Range **pv, const HVL_Context *ctx, double from, double to, double step, double a0, double a1, double a2, double a3, fpcalcfun calcfun)
{
	HVL_THREAD *threads;
	ThreadParams *tps = nullptr;
	bool bret;
	size_t idx;
	HVL_Pair *buffer;
#ifdef LIBHVL_THREADING_WIN32
	DWORD *threadIDs;
#elif defined LIBHVL_THREADING_PTHREAD
	int ret;
#else
	#error "No threading model has been specified"
#endif // LIBHVL_THREADING_
	const size_t count = (size_t)floor(((to - from) / step) + 0.5);
	if (count < 1)
		return false;

	const size_t numThreads = GetNumThreads(count);
	const size_t itersPerThread = count / numThreads;

	try {
		threads = new HVL_THREAD[numThreads];
	} catch (std::bad_alloc&) {
		return false;
	}
#ifdef LIBHVL_THREADING_WIN32
	try {
		threadIDs = new DWORD[numThreads];
	} catch (std::bad_alloc&) {
		delete[] threads;
		return false;
	}
#endif // LIBHVL_THREADING_WIN32

	try {
		tps = new ThreadParams[numThreads];
	} catch (std::bad_alloc&) {
		bret = false;
		goto out;
	}

	*pv = HVL_alloc_range(count);
	if (*pv == nullptr) {
		bret = false;
		goto out;
	}

	buffer = (*pv)->p;

	for (idx = 0; idx < numThreads; idx++) {
		tps[idx].buffer = buffer + (itersPerThread * idx);
		tps[idx].ctx = ctx;
		tps[idx].from = from + (idx * step * itersPerThread);
		tps[idx].step = step;
		tps[idx].iters = itersPerThread;
		tps[idx].a0 = a0;
		tps[idx].a1 = a1;
		tps[idx].a2 = a2;
		tps[idx].a3 = a3;
		tps[idx].calcfun = calcfun;
	}
	/* Make an adjustment for the last thread */
	tps[numThreads - 1].iters = count - (itersPerThread * (numThreads - 1)); /* Make sure that we do not leave out anything due to rounding */

	/* Launch threads */
	for (idx = 0; idx < numThreads; idx++) {
	#ifdef LIBHVL_THREADING_WIN32
		threads[idx] = CreateThread(NULL, 0, WorkerFunc, &tps[idx], 0, &threadIDs[idx]);
		if (threads[idx] == 0)
			goto err_unwind;
	#elif defined LIBHVL_THREADING_PTHREAD
		ret = pthread_create(&threads[idx], NULL, WorkerFunc, &tps[idx]);
		if (ret)
			goto err_unwind;
	#endif // LIBHVL_THREADING_
	}

#ifdef LIBHVL_THREADING_WIN32
	WaitForMultipleObjects(numThreads, threads, TRUE, INFINITE);
	for (idx = 0; idx < numThreads; idx++)
		CloseHandle(threads[idx]);
#elif defined LIBHVL_THREADING_PTHREAD
	for (size_t idx = 0; idx < numThreads; idx++)
		pthread_join(threads[idx], NULL);
#endif // LIBHVL_THREADING_
	bret = true;
	goto out;

/* Something went wrong when we were starting the workers, terminate
   all workers that might have been started and exit */
err_unwind:
	bret = false;
	for (;;) {
	#ifdef LIBHVL_THREADING_WIN32
		TerminateThread(threads[idx], WAIT_OBJECT_0);
		CloseHandle(threads[idx]);
	#elif defined LIBHVL_THREADING_PTHREAD
		int _ret;
		void *retval;

		pthread_cancel(threads[idx]);
		_ret = pthread_join(threads[idx], &retval);
		if (_ret)
			abort();  /* Something has gone very wrong when killing the thread */
	#endif // LIBHVL_THREADING_
		if (idx == 0)
			break;
		else
			idx--;
	}
	HVL_free_range(*pv);
	*pv = nullptr;
out:
	delete[] tps;
	delete[] threads;
#ifdef LIBHVL_THREADING_WIN32
	delete[] threadIDs;
#endif // LIBHVL_THREADING_WIN32

	return bret;
}
コード例 #5
0
ファイル: taskmanager.cpp プロジェクト: ddrake/ngsolve
  void TaskManager :: Loop(int thd)
  {
    /*
    static Timer tADD("add entry counter");
    static Timer tCASready1("spin-CAS ready tick1");
    static Timer tCASready2("spin-CAS ready tick2");
    static Timer tCASyield("spin-CAS yield");
    static Timer tCAS1("spin-CAS wait");
    static Timer texit("exit zone");
    static Timer tdec("decrement");
    */
    thread_id = thd;

    int thds = GetNumThreads();

    int mynode = num_nodes * thd/thds;

    NodeData & mynode_data = *(nodedata[mynode]);



    TaskInfo ti;
    ti.nthreads = thds;
    ti.thread_nr = thd;
    // ti.nnodes = num_nodes;
    // ti.node_nr = mynode;

      
#ifdef USE_NUMA
    numa_run_on_node (mynode);
#endif
    active_workers++;
    workers_on_node[mynode]++;
    int jobdone = 0;


#ifdef USE_MKL
    auto mkl_max = mkl_get_max_threads();
    mkl_set_num_threads_local(1);
#endif

    
    while (!done)
      {
        if (complete[mynode] > jobdone)
          jobdone = complete[mynode];

        if (jobnr == jobdone)
          {
            // RegionTracer t(ti.thread_nr, tCASyield, ti.task_nr);            
            if(sleep)
              this_thread::sleep_for(chrono::microseconds(sleep_usecs));
            else
              {
#ifdef WIN32
                this_thread::yield();
#else  // WIN32
                sched_yield();
#endif // WIN32
              }
            continue;
          }

        {
          // RegionTracer t(ti.thread_nr, tADD, ti.task_nr);

          // non-atomic fast check ...
          if ( (mynode_data.participate & 1) == 0) continue;

          int oldval = mynode_data.participate += 2;
          if ( (oldval & 1) == 0)
            { // job not active, going out again
              mynode_data.participate -= 2;
              continue;
            }
        }

        if (startup_function) (*startup_function)();
        
        IntRange mytasks = Range(int(ntasks)).Split (mynode, num_nodes);
          
        try
          {
            
            while (1)
              {
                if (mynode_data.start_cnt >= mytasks.Size()) break;
		int mytask = mynode_data.start_cnt.fetch_add(1, memory_order_relaxed);
                if (mytask >= mytasks.Size()) break;
                
                ti.task_nr = mytasks.First()+mytask;
                ti.ntasks = ntasks;
                
                {
                  RegionTracer t(ti.thread_nr, jobnr, RegionTracer::ID_JOB, ti.task_nr);
                  (*func)(ti);
                }
              }

          }
        catch (Exception e)
          {
            {
              // cout << "got exception in TM" << endl; 
              lock_guard<mutex> guard(copyex_mutex);
              delete ex;
              ex = new Exception (e);
              mynode_data.start_cnt = mytasks.Size();
            }
          }

#ifndef __MIC__
        atomic_thread_fence (memory_order_release);     
#endif // __MIC__

        if (cleanup_function) (*cleanup_function)();

        jobdone = jobnr;

        mynode_data.participate-=2;

	{
	  int oldpart = 1;
	  if (mynode_data.participate.compare_exchange_strong (oldpart, 0))
	    {
              if (jobdone < jobnr.load())
                { // reopen gate
                  mynode_data.participate |= 1;                  
                }
              else
                {
                  if (mynode != 0)
                    mynode_data.start_cnt = 0;
                  complete[mynode] = jobnr.load(); 
                }
	    }	      
	}
      }
    

#ifdef USE_MKL
    mkl_set_num_threads_local(mkl_max);
#endif

    workers_on_node[mynode]--;
    active_workers--;
  }
コード例 #6
0
ファイル: taskmanager.cpp プロジェクト: ddrake/ngsolve
  void TaskManager :: CreateJob (const function<void(TaskInfo&)> & afunc,
                                 int antasks)
  {
    if (num_threads == 1 || !task_manager || func)
      {
        if (startup_function) (*startup_function)();
        
        TaskInfo ti;
        ti.ntasks = antasks;
        ti.thread_nr = 0; ti.nthreads = 1;
        // ti.node_nr = 0; ti.nnodes = 1;
        for (ti.task_nr = 0; ti.task_nr < antasks; ti.task_nr++)
          afunc(ti);

        if (cleanup_function) (*cleanup_function)();        
        return;
      }

    
    trace->StartJob(jobnr, afunc.target_type());

    func = &afunc;

    ntasks.store (antasks); // , memory_order_relaxed);
    ex = nullptr;


    nodedata[0]->start_cnt.store (0, memory_order_relaxed);

    jobnr++;
    
    for (int j = 0; j < num_nodes; j++)
      nodedata[j]->participate |= 1;

    if (startup_function) (*startup_function)();
    
    int thd = 0;
    int thds = GetNumThreads();
    int mynode = num_nodes * thd/thds;

    IntRange mytasks = Range(int(ntasks)).Split (mynode, num_nodes);
    NodeData & mynode_data = *(nodedata[mynode]);

    TaskInfo ti;
    ti.nthreads = thds;
    ti.thread_nr = thd;
    // ti.nnodes = num_nodes;
    // ti.node_nr = mynode;

    try
      {
        while (1)
          {
            int mytask = mynode_data.start_cnt++;
            if (mytask >= mytasks.Size()) break;
            
            ti.task_nr = mytasks.First()+mytask;
            ti.ntasks = ntasks;

            {
              RegionTracer t(ti.thread_nr, jobnr, RegionTracer::ID_JOB, ti.task_nr);
              (*func)(ti); 
            }
          }

      }
    catch (Exception e)
      {
        {
          lock_guard<mutex> guard(copyex_mutex);
          delete ex;
          ex = new Exception (e);
          mynode_data.start_cnt = mytasks.Size();
        }
      }

    if (cleanup_function) (*cleanup_function)();
    
    for (int j = 0; j < num_nodes; j++)
      if (workers_on_node[j])
        {
          while (complete[j] != jobnr)
            _mm_pause();
        }

    func = nullptr;
    if (ex)
      throw Exception (*ex);

    trace->StopJob();
  }