Esempio n. 1
0
void ForEach(const C& Enumerable, FUNCTION Function)
{
    auto enumerator = Enumerable.GetEnumerator();
    
    RF_Type::Size elements = enumerator.Size();
    RF_Type::UInt32 worker, cport;
    RF_Pattern::Singleton<RF_Thread::ThreadPool>::GetInstance().GetThreadCount(worker, cport);
    RF_Type::UInt32 jobsPerWorker = 0;    
    RF_Type::AtomicInt32 overallWork(elements);
    RF_Type::UInt32 extra = 1;
    
    if(elements > worker)
    {
        jobsPerWorker = elements / worker;
        elements -= jobsPerWorker * worker;
    }
    else
    {
        jobsPerWorker = 1;
        worker = elements;
        extra = 0;
    }
    
    for(RF_Type::UInt32 i = 0, offset = 0; i < worker; ++i)
    {
        if(elements <= i)
            extra = 0;
        auto* task = new ForEachEnumeratorTaskData<C, FUNCTION>(Function);
        task->Enumeable = enumerator;
        task->From = offset;
        task->Steps = jobsPerWorker + extra;
        task->OverallWork = &overallWork; 
        RF_Pattern::Singleton<RF_Thread::ThreadPool>::GetInstance().QueueUserWorkItem(ForEachEnumeratorTaskFunction<C, FUNCTION>, task);
        offset += jobsPerWorker + extra;
    }
    
    // Wait for other threads. Sleep(0) will ensure that the thread return if no
    // other process/thread will work for the rest of the time slice on this core.
    Time::TimeSpan sleep = Time::TimeSpan::CreateByTicks(0);
    while(overallWork != 0)
    {
        System::Threading::Thread::Sleep(sleep);
    }
}
Esempio n. 2
0
Memory::AutoPointerArray<RF_Type::Size>
FindAll(const C& Enumerable, FUNCTION Function)
{
  auto enumerator = Enumerable.GetConstEnumerator();
  RF_Type::Size elements = enumerator.Size();
  RF_Type::AtomicInt32 hits;
  RF_Collect::Array<RF_Type::UInt8> results(elements);

  if(RF_Pattern::Singleton<RF_Thread::ThreadPool>::GetInstance().CanQueue())
  {
    RF_Type::UInt32 worker;
    RF_Pattern::Singleton<RF_Thread::ThreadPool>::GetInstance().GetThreadCount(
        worker);
    RF_Type::UInt32 jobsPerWorker = 0;
    RF_Type::AtomicInt32 overallWork(elements);
    RF_Type::UInt32 extra = 1;

    if(elements > worker)
    {
      jobsPerWorker = elements / worker;
      elements -= jobsPerWorker * worker;
    }
    else
    {
      jobsPerWorker = 1;
      worker = elements;
      extra = 0;
    }

    for(RF_Type::UInt32 i = 0, offset = 0; i < worker; ++i)
    {
      if(elements <= i)
      {
        extra = 0;
      }
      auto* task = new FindAllEnumeratorTaskData<C, FUNCTION>(Function);
      task->Enumeable = enumerator;
      task->From = offset;
      task->Steps = jobsPerWorker + extra;
      task->OverallWork = &overallWork;
      task->Results = &results;
      task->Hits = &hits;
      RF_Pattern::Singleton<RF_Thread::ThreadPool>::GetInstance()
          .QueueUserWorkItem(FindAllEnumeratorTaskFunction<C, FUNCTION>, task);
      offset += jobsPerWorker + extra;
    }

    // Wait for other threads. Sleep(0) will ensure that the thread return if no
    // other process/thread will work for the rest of the time slice on this
    // core.
    RF_Time::TimeSpan sleep = RF_Time::TimeSpan::CreateByTicks(0);
    while(overallWork != 0)
    {
      RF_Thread::Thread::Sleep(sleep);
    }
  }
  else
  {
    for(RF_Type::Size i = 0; i < elements; ++i, ++enumerator)
    {
      if(Function(enumerator))
      {
        hits.Increment();
        results(i) = 1;
      }
      else
      {
        results(i) = 0;
      }
    }
  }

  RF_Mem::AutoPointerArray<RF_Type::Size> result(hits);
  for(RF_Type::Size i = 0, ci = 0; i < enumerator.Size(); ++i)
  {
    if(results(i) == 1)
    {
      result[ci] = i;
      ++ci;
    }
  }
  return result;
}