CMS 3D CMS Logo

Classes | Public Member Functions | Private Member Functions | Private Attributes | Friends

edm::SerialTaskQueue Class Reference

#include <SerialTaskQueue.h>

List of all members.

Classes

class  QueuedTask
class  TaskBase

Public Member Functions

template<typename T >
void push (const T &iAction)
 asynchronously pushes functor iAction into queue
template<typename T >
tbb::task * pushAndGetNextTaskToRun (const T &iAction)
 asynchronously pushes functor iAction into queue and finds next task to execute
template<typename T >
void pushAndWait (const T &iAction)
 synchronously pushes functor iAction into queue
 SerialTaskQueue ()

Private Member Functions

tbb::task * finishedTask ()
const SerialTaskQueueoperator= (const SerialTaskQueue &)
TaskBasepickNextTask ()
tbb::task * pushAndGetNextTask (TaskBase *)
void pushAndWait (tbb::empty_task *iWait, TaskBase *)
void pushTask (TaskBase *)
 SerialTaskQueue (const SerialTaskQueue &)

Private Attributes

std::atomic< unsigned long > m_pauseCount
std::atomic_flag m_taskChosen
tbb::concurrent_queue< TaskBase * > m_tasks

Friends

class TaskBase

Detailed Description

Definition at line 65 of file SerialTaskQueue.h.


Constructor & Destructor Documentation

edm::SerialTaskQueue::SerialTaskQueue ( ) [inline]

Definition at line 68 of file SerialTaskQueue.h.

                       :
      m_taskChosen{ATOMIC_FLAG_INIT},
edm::SerialTaskQueue::SerialTaskQueue ( const SerialTaskQueue ) [private]

Member Function Documentation

tbb::task * SerialTaskQueue::finishedTask ( ) [private]
const SerialTaskQueue& edm::SerialTaskQueue::operator= ( const SerialTaskQueue ) [private]
SerialTaskQueue::TaskBase * SerialTaskQueue::pickNextTask ( ) [private]

Definition at line 64 of file SerialTaskQueue.cc.

References likely, m_pauseCount, m_taskChosen, m_tasks, and lumiQTWidget::t.

Referenced by finishedTask(), and pushAndGetNextTask().

                              {
  
  if likely(0 == m_pauseCount and not m_taskChosen.test_and_set()) {
    TaskBase* t=0;
    if likely(m_tasks.try_pop(t)) {
      return t;
    }
    //no task was actually pulled
    m_taskChosen.clear();
    
    //was a new entry added after we called 'try_pop' but before we did the clear?
    if(not m_tasks.empty() and not m_taskChosen.test_and_set()) {
      TaskBase* t=0;
      if(m_tasks.try_pop(t)) {
        return t;
      }
      //no task was still pulled since a different thread beat us to it
      m_taskChosen.clear();
      
    }
  }
  return 0;
}
template<typename T >
void SerialTaskQueue::push ( const T iAction)

asynchronously pushes functor iAction into queue

The function will return immediately and iAction will either process concurrently with the calling thread or wait until the protected resource becomes available or until a CPU becomes available.

Parameters:
[in]iActionMust be a functor that takes no arguments and return no values.

Definition at line 184 of file SerialTaskQueue.h.

References pushTask().

                                              {
      QueuedTask<T>* pTask{ new (tbb::task::allocate_root()) QueuedTask<T>{iAction} };
      pTask->setQueue(this);
      pushTask(pTask);
   }
tbb::task * SerialTaskQueue::pushAndGetNextTask ( TaskBase iTask) [private]

Definition at line 47 of file SerialTaskQueue.cc.

References likely, m_tasks, and pickNextTask().

Referenced by pushAndGetNextTaskToRun(), pushAndWait(), and pushTask().

                                                   {
  tbb::task* returnValue{0};
  if likely(0!=iTask) {
    m_tasks.push(iTask);
    returnValue = pickNextTask();
  }
  return returnValue;
}
template<typename T >
tbb::task * SerialTaskQueue::pushAndGetNextTaskToRun ( const T iAction)

asynchronously pushes functor iAction into queue and finds next task to execute

This function is useful if you are accessing the SerialTaskQueue for the execute() method of a TBB task and want to efficiently schedule the next task from the queue. In that case you can take the return value and return it directly from your execute() method. The function will return immediately and not wait for iAction to run.

Parameters:
[in]iActionMust be a functor that takes no arguments and return no values.
Returns:
Returns either the next task that the user must schedule with TBB or a nullptr.

Definition at line 200 of file SerialTaskQueue.h.

References pushAndGetNextTask().

                                                                     {
      QueuedTask<T>* pTask{ new (tbb::task::allocate_root()) QueuedTask<T>{iAction} };
      pTask->setQueue(this);
      return pushAndGetNextTask(pTask);
   }
template<typename T >
void SerialTaskQueue::pushAndWait ( const T iAction)

synchronously pushes functor iAction into queue

The function will wait until iAction has completed before returning. If another task is already running on the queue, the system is allowed to find another TBB task to execute while waiting for the iAction to finish. In that way the core is not idled while waiting.

Parameters:
[in]iActionMust be a functor that takes no arguments and return no values.

Definition at line 191 of file SerialTaskQueue.h.

                                                     {
      tbb::empty_task* waitTask = new (tbb::task::allocate_root()) tbb::empty_task;
      waitTask->set_ref_count(2);
      QueuedTask<T>* pTask{ new (waitTask->allocate_child()) QueuedTask<T>{iAction} };
      pTask->setQueue(this);
      pushAndWait(waitTask,pTask);
   }
void SerialTaskQueue::pushAndWait ( tbb::empty_task *  iWait,
TaskBase iTask 
) [private]

Definition at line 88 of file SerialTaskQueue.cc.

References pyrootRender::destroy(), likely, and pushAndGetNextTask().

                                                                       {
   auto nextTask = pushAndGetNextTask(iTask);
   if likely(nullptr != nextTask) {
     if likely(nextTask == iTask) {
        //spawn and wait for all requires the task to have its parent set
        iWait->spawn_and_wait_for_all(*nextTask);
     } else {
        tbb::task::spawn(*nextTask);
        iWait->wait_for_all();
     }
   } else {
     //a task must already be running in this queue
     iWait->wait_for_all();              
   }
   tbb::task::destroy(*iWait);
}
void SerialTaskQueue::pushTask ( TaskBase iTask) [private]

Definition at line 39 of file SerialTaskQueue.cc.

References pushAndGetNextTask(), and lumiQTWidget::t.

Referenced by push().

                                         {
  tbb::task* t = pushAndGetNextTask(iTask);
  if(0!=t) {
    tbb::task::spawn(*t);      
  }
}

Friends And Related Function Documentation

friend class TaskBase [friend]

Definition at line 166 of file SerialTaskQueue.h.


Member Data Documentation

std::atomic<unsigned long> edm::SerialTaskQueue::m_pauseCount [private]

Definition at line 180 of file SerialTaskQueue.h.

Referenced by pickNextTask().

std::atomic_flag edm::SerialTaskQueue::m_taskChosen [private]

Definition at line 179 of file SerialTaskQueue.h.

Referenced by finishedTask(), and pickNextTask().

tbb::concurrent_queue<TaskBase*> edm::SerialTaskQueue::m_tasks [private]

Definition at line 178 of file SerialTaskQueue.h.

Referenced by pickNextTask(), and pushAndGetNextTask().