add frame_sync flag

This commit is contained in:
David Rose 2009-12-05 19:04:39 +00:00
parent 44dba03a49
commit ea31a192b0
2 changed files with 59 additions and 4 deletions

View File

@ -43,6 +43,7 @@ AsyncTaskChain(AsyncTaskManager *manager, const string &name) :
_num_threads(0),
_thread_priority(TP_normal),
_frame_budget(-1.0),
_frame_sync(false),
_num_busy_threads(0),
_num_tasks(0),
_state(S_initial),
@ -50,7 +51,8 @@ AsyncTaskChain(AsyncTaskManager *manager, const string &name) :
_pickup_mode(false),
_needs_cleanup(false),
_current_frame(0),
_time_in_frame(0.0)
_time_in_frame(0.0),
_block_till_next_frame(false)
{
}
@ -216,6 +218,43 @@ get_frame_budget() const {
return _frame_budget;
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskChain::set_frame_sync
// Access: Published
// Description: Sets the frame_sync flag. When this flag is true,
// this task chain will be forced to sync with the
// TaskManager's clock. It will run no faster than one
// epoch per clock frame.
//
// When this flag is false, the default, the task chain
// will finish all of its tasks and then immediately
// start from the first task again, regardless of the
// clock frame. When it is true, the task chain will
// finish all of its tasks and then wait for the clock
// to tick to the next frame before resuming the first
// task.
//
// This only makes sense for threaded task chains.
// Non-threaded task chains are automatically
// synchronous.
////////////////////////////////////////////////////////////////////
void AsyncTaskChain::
set_frame_sync(bool frame_sync) {
MutexHolder holder(_manager->_lock);
_frame_sync = frame_sync;
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskChain::get_frame_sync
// Access: Published
// Description: Returns the frame_sync flag. See set_frame_sync().
////////////////////////////////////////////////////////////////////
bool AsyncTaskChain::
get_frame_sync() const {
MutexHolder holder(_manager->_lock);
return _frame_sync;
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskChain::set_timeslice_priority
// Access: Published
@ -924,6 +963,11 @@ finish_sort_group() {
}
_manager->_clock->tick();
_manager->_frame_cvar.notify_all();
} else if (_frame_sync) {
// If we're a synced chain, we have to wait at the end of the
// epoch for someone else to tick the clock.
_block_till_next_frame = true;
}
// Check for any sleeping tasks that need to be woken.
@ -1239,8 +1283,10 @@ do_poll() {
if (_current_frame != frame) {
_current_frame = frame;
_time_in_frame = 0.0;
_block_till_next_frame = false;
}
if (_frame_budget >= 0.0 && _time_in_frame >= _frame_budget) {
if (_block_till_next_frame ||
(_frame_budget >= 0.0 && _time_in_frame >= _frame_budget)) {
// If we've exceeded our budget, stop here. We'll resume from
// this point at the next call to poll().
cleanup_pickup_mode();
@ -1479,12 +1525,15 @@ thread_main() {
if (_chain->_current_frame != frame) {
_chain->_current_frame = frame;
_chain->_time_in_frame = 0.0;
_chain->_block_till_next_frame = false;
}
// If we've exceeded our frame budget, sleep until the next
// frame.
if (_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget) {
while (_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget &&
if (_chain->_block_till_next_frame ||
(_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget)) {
while ((_chain->_block_till_next_frame ||
(_chain->_frame_budget >= 0.0 && _chain->_time_in_frame >= _chain->_frame_budget)) &&
_chain->_state != S_shutdown && _chain->_state != S_interrupted) {
_chain->cleanup_pickup_mode();
_chain->_manager->_frame_cvar.wait();
@ -1492,6 +1541,7 @@ thread_main() {
if (_chain->_current_frame != frame) {
_chain->_current_frame = frame;
_chain->_time_in_frame = 0.0;
_chain->_block_till_next_frame = false;
}
}
// Now that it's the next frame, go back to the top of the loop.

View File

@ -73,6 +73,9 @@ PUBLISHED:
void set_frame_budget(double frame_budget);
double get_frame_budget() const;
void set_frame_sync(bool frame_sync);
bool get_frame_sync() const;
void set_timeslice_priority(bool timeslice_priority);
bool get_timeslice_priority() const;
@ -173,6 +176,7 @@ protected:
ThreadPriority _thread_priority;
Threads _threads;
double _frame_budget;
bool _frame_sync;
int _num_busy_threads;
int _num_tasks;
TaskHeap _active;
@ -186,6 +190,7 @@ protected:
int _current_frame;
double _time_in_frame;
bool _block_till_next_frame;
static PStatCollector _task_pcollector;
static PStatCollector _wait_pcollector;