Thread::get_current_task()

This commit is contained in:
David Rose 2010-02-09 20:14:58 +00:00
parent 7c3bd0bd8d
commit 2494b49728
11 changed files with 192 additions and 6 deletions

View File

@ -443,10 +443,13 @@ unlock_and_do_task() {
nassertr(_manager != (AsyncTaskManager *)NULL, DS_done);
PT(ClockObject) clock = _manager->get_clock();
Thread *current_thread = Thread::get_current_thread();
record_task(current_thread);
// It's important to release the lock while the task is being
// serviced.
_manager->_lock.release();
double start = clock->get_real_time();
_task_pcollector.start();
DoneStatus status = do_task();
@ -462,6 +465,8 @@ unlock_and_do_task() {
_chain->_time_in_frame += _dt;
clear_task(current_thread);
return status;
}

View File

@ -17,8 +17,7 @@
#include "pandabase.h"
#include "typedReferenceCount.h"
#include "namable.h"
#include "asyncTaskBase.h"
#include "pmutex.h"
#include "conditionVar.h"
#include "pStatCollector.h"
@ -41,7 +40,7 @@ class AsyncTaskChain;
// class, and override do_task(), to define the
// functionality you wish to have the task perform.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT AsyncTask : public TypedReferenceCount, public Namable {
class EXPCL_PANDA_EVENT AsyncTask : public AsyncTaskBase {
public:
AsyncTask(const string &name = string());
ALLOC_DELETED_CHAIN(AsyncTask);
@ -162,9 +161,9 @@ public:
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
AsyncTaskBase::init_type();
register_type(_type_handle, "AsyncTask",
TypedReferenceCount::get_class_type());
AsyncTaskBase::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -11,6 +11,7 @@
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
asyncTaskBase.h asyncTaskBase.I \
contextSwitch.c contextSwitch.h \
blockerSimple.h blockerSimple.I \
conditionVar.h conditionVar.I \
@ -70,6 +71,7 @@
threadPriority.h
#define INCLUDED_SOURCES \
asyncTaskBase.cxx \
conditionVar.cxx \
conditionVarDebug.cxx \
conditionVarDirect.cxx \
@ -123,6 +125,7 @@
threadPriority.cxx
#define INSTALL_HEADERS \
asyncTaskBase.h asyncTaskBase.I \
contextSwitch.h \
blockerSimple.h blockerSimple.I \
conditionVar.h conditionVar.I \

View File

@ -0,0 +1,14 @@
// Filename: asyncTaskBase.I
// Created by: drose (09Feb10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,80 @@
// Filename: asyncTaskBase.cxx
// Created by: drose (09Feb10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "asyncTaskBase.h"
#include "thread.h"
#include "atomicAdjust.h"
TypeHandle AsyncTaskBase::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskBase::Constructor
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
AsyncTaskBase::
AsyncTaskBase() {
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskBase::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
AsyncTaskBase::
~AsyncTaskBase() {
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskBase::record_task
// Access: Protected
// Description: Indicates that this task is now the current task
// running on the indicated thread, presumably the
// current thread.
////////////////////////////////////////////////////////////////////
void AsyncTaskBase::
record_task(Thread *current_thread) {
nassertv(current_thread->_current_task == NULL);
void *result = AtomicAdjust::compare_and_exchange_ptr
((void * TVOLATILE &)current_thread->_current_task,
(void *)NULL, (void *)this);
// If the return value is other than NULL, someone else must have
// assigned the task first, in another thread. That shouldn't be
// possible.
nassertv(result == NULL);
nassertv(current_thread->_current_task == this);
}
////////////////////////////////////////////////////////////////////
// Function: AsyncTaskBase::clear_task
// Access: Protected
// Description: Indicates that this task is no longer running on the
// indicated thread.
////////////////////////////////////////////////////////////////////
void AsyncTaskBase::
clear_task(Thread *current_thread) {
nassertv(current_thread->_current_task == this);
void *result = AtomicAdjust::compare_and_exchange_ptr
((void * TVOLATILE &)current_thread->_current_task,
(void *)this, (void *)NULL);
// If the return value is other than this, someone else must have
// assigned the task first, in another thread. That shouldn't be
// possible.
nassertv(result == this);
nassertv(current_thread->_current_task == NULL);
}

View File

@ -0,0 +1,64 @@
// Filename: asyncTaskBase.h
// Created by: drose (09Feb10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef ASYNCTASKBASE_H
#define ASYNCTASKBASE_H
#include "pandabase.h"
#include "typedReferenceCount.h"
#include "namable.h"
class Thread;
////////////////////////////////////////////////////////////////////
// Class : AsyncTaskBase
// Description : The abstract base class for AsyncTask. This is
// defined here only so we can store a pointer to the
// current task on the Thread.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PIPELINE AsyncTaskBase : public TypedReferenceCount, public Namable {
protected:
AsyncTaskBase();
public:
ALLOC_DELETED_CHAIN(AsyncTaskBase);
PUBLISHED:
virtual ~AsyncTaskBase();
protected:
void record_task(Thread *current_thread);
void clear_task(Thread *current_thread);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "AsyncTaskBase",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "asyncTaskBase.I"
#endif

View File

@ -13,6 +13,7 @@
////////////////////////////////////////////////////////////////////
#include "config_pipeline.h"
#include "asyncTaskBase.h"
#include "mainThread.h"
#include "externalThread.h"
#include "thread.h"
@ -69,6 +70,7 @@ init_libpipeline() {
}
initialized = true;
AsyncTaskBase::init_type();
MainThread::init_type();
ExternalThread::init_type();
Thread::init_type();

View File

@ -1,3 +1,4 @@
#include "asyncTaskBase.cxx"
#include "conditionVar.cxx"
#include "conditionVarDebug.cxx"
#include "conditionVarDirect.cxx"

View File

@ -298,6 +298,18 @@ preempt() {
}
}
////////////////////////////////////////////////////////////////////
// Function: Thread::get_current_task
// Access: Published
// Description: Returns the task currently executing on this thread
// (via the AsyncTaskManager), if any, or NULL if the
// thread is not currently servicing a task.
////////////////////////////////////////////////////////////////////
INLINE AsyncTaskBase *Thread::
get_current_task() const {
return _current_task;
}
////////////////////////////////////////////////////////////////////
// Function: Thread::prepare_for_exit
// Access: Published

View File

@ -53,6 +53,7 @@ Thread(const string &name, const string &sync_name) :
_pstats_callback = NULL;
_pipeline_stage = 0;
_joinable = false;
_current_task = NULL;
#ifdef HAVE_PYTHON
_python_data = Py_None;

View File

@ -34,6 +34,7 @@ class ReMutex;
class MutexDebug;
class ConditionVarDebug;
class ConditionVarFullDebug;
class AsyncTaskBase;
////////////////////////////////////////////////////////////////////
// Class : Thread
@ -100,6 +101,8 @@ PUBLISHED:
PyObject *get_python_data() const;
#endif
INLINE AsyncTaskBase *get_current_task() const;
INLINE static void prepare_for_exit();
public:
@ -136,6 +139,7 @@ private:
int _pipeline_stage;
PStatsCallback *_pstats_callback;
bool _joinable;
AsyncTaskBase *_current_task;
#ifdef HAVE_PYTHON
PyObject *_python_data;
@ -179,6 +183,7 @@ private:
friend class ThreadPosixImpl;
friend class ThreadSimpleImpl;
friend class MainThread;
friend class AsyncTaskBase;
};
INLINE ostream &operator << (ostream &out, const Thread &thread);