You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
12 KiB
389 lines
12 KiB
/* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group |
|
* |
|
* This library is open source and may be redistributed and/or modified under |
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|
* (at your option) any later version. The full license is in LICENSE file |
|
* included with this distribution, and on the openscenegraph.org website. |
|
* |
|
* This library is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* OpenSceneGraph Public License for more details. |
|
*/ |
|
|
|
|
|
// |
|
// Thread - C++ Thread class |
|
// ~~~~~~~~ |
|
// |
|
|
|
#ifndef _OPENTHREADS_THREAD_ |
|
#define _OPENTHREADS_THREAD_ |
|
|
|
#include <sys/types.h> |
|
|
|
#include <OpenThreads/Mutex> |
|
|
|
namespace OpenThreads { |
|
|
|
/** |
|
* Get the number of processors. |
|
* |
|
* Note, systems where no support exists for querrying the number of processors, 1 is returned. |
|
* |
|
*/ |
|
extern OPENTHREAD_EXPORT_DIRECTIVE int GetNumberOfProcessors(); |
|
|
|
/** |
|
* Set the processor affinity of current thread. |
|
* |
|
* Note, systems where no support exists no affinity will be set, and -1 will be returned. |
|
* |
|
*/ |
|
extern OPENTHREAD_EXPORT_DIRECTIVE int SetProcessorAffinityOfCurrentThread(unsigned int cpunum); |
|
|
|
/** |
|
* @class Thread |
|
* @brief This class provides an object-oriented thread interface. |
|
*/ |
|
class OPENTHREAD_EXPORT_DIRECTIVE Thread { |
|
|
|
public: |
|
|
|
/** |
|
* Set the concurrency level for a running application. This method |
|
* only has effect if the pthreads thread model is being used, and |
|
* then only when that model is many-to-one (eg. irix). |
|
* in other cases it is ignored. The concurrency level is only a |
|
* *hint* as to the number of execution vehicles to use, the actual |
|
* implementation may do anything it wants. Setting the value |
|
* to 0 returns things to their default state. |
|
* |
|
* @return previous concurrency level, -1 indicates no-op. |
|
*/ |
|
static int SetConcurrency(int concurrencyLevel); |
|
|
|
/** |
|
* Get the concurrency level for a running application. In this |
|
* case, a return code of 0 means that the application is in default |
|
* mode. A return code of -1 means that the application is incapable |
|
* of setting an arbitrary concurrency, because it is a one-to-one |
|
* execution model (sprocs, linuxThreads) |
|
*/ |
|
static int GetConcurrency(); |
|
|
|
/** |
|
* Enumerated Type for thread priority |
|
*/ |
|
enum ThreadPriority { |
|
|
|
THREAD_PRIORITY_MAX, /**< The maximum possible priority */ |
|
THREAD_PRIORITY_HIGH, /**< A high (but not max) setting */ |
|
THREAD_PRIORITY_NOMINAL, /**< An average priority */ |
|
THREAD_PRIORITY_LOW, /**< A low (but not min) setting */ |
|
THREAD_PRIORITY_MIN, /**< The miniumum possible priority */ |
|
THREAD_PRIORITY_DEFAULT /**< Priority scheduling default */ |
|
|
|
}; |
|
|
|
/** |
|
* Enumerated Type for thread scheduling policy |
|
*/ |
|
enum ThreadPolicy { |
|
|
|
THREAD_SCHEDULE_FIFO, /**< First in, First out scheduling */ |
|
THREAD_SCHEDULE_ROUND_ROBIN, /**< Round-robin scheduling (LINUX_DEFAULT) */ |
|
THREAD_SCHEDULE_TIME_SHARE, /**< Time-share scheduling (IRIX DEFAULT) */ |
|
THREAD_SCHEDULE_DEFAULT /**< Default scheduling */ |
|
|
|
}; |
|
|
|
/** |
|
* Constructor |
|
*/ |
|
Thread(); |
|
|
|
/** |
|
* Destructor |
|
*/ |
|
virtual ~Thread(); |
|
|
|
|
|
/** |
|
* Return a pointer to the current running thread |
|
*/ |
|
static Thread *CurrentThread(); |
|
|
|
|
|
/** |
|
* Initialize Threading in a program. This method must be called before |
|
* you can do any threading in a program. |
|
*/ |
|
static void Init(); |
|
|
|
/** |
|
* Yield the processor. |
|
* |
|
* @note This method operates on the calling process. And is |
|
* equivalent to calling sched_yield(). |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
static int YieldCurrentThread(); |
|
|
|
/** |
|
* This method will return the ThreadPriority of the master process. |
|
* (ie, the one calling the thread->start() methods for the first time) |
|
* The method will almost certainly return |
|
* Thread::THREAD_PRIORITY_DEFAULT if |
|
* Init() has not been called. |
|
* |
|
* @return the Thread::ThreadPriority of the master thread. |
|
*/ |
|
static ThreadPriority GetMasterPriority() {return s_masterThreadPriority;}; |
|
|
|
|
|
/** |
|
* Get a unique thread id. This id is monotonically increasing. |
|
* |
|
* @return a unique thread identifier |
|
*/ |
|
int getThreadId(); |
|
|
|
/** |
|
* Get the thread's process id. This is the pthread_t or pid_t value |
|
* depending on the threading model being used. |
|
* |
|
* @return thread process id. |
|
*/ |
|
size_t getProcessId(); |
|
|
|
/** |
|
* Start the thread. This method will configure the thread, set |
|
* it's priority, and spawn it. |
|
* |
|
* @note if the stack size specified setStackSize is smaller than the |
|
* smallest allowable stack size, the threads stack size will be set to |
|
* the minimum allowed, and may be retrieved via the getStackSize() |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int start(); |
|
int startThread(); |
|
|
|
/** |
|
* Test the cancel state of the thread. If the thread has been canceled |
|
* this method will cause the thread to exit now. This method operates |
|
* on the calling thread. |
|
* |
|
* Returns 0 if normal, -1 if called from a thread other that this. |
|
*/ |
|
int testCancel(); |
|
|
|
|
|
/** |
|
* Cancel the thread. Equivalent to SIGKILL. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
virtual int cancel(); |
|
|
|
/** |
|
* Set the thread's schedule priority. This is a complex method. |
|
* Beware of thread priorities when using a many-to-many kernel |
|
* entity implemenation (such as IRIX pthreads). If one is not carefull |
|
* to manage the thread priorities, a priority inversion deadlock can |
|
* easily occur (Although the OpenThreads::Mutex & OpenThreads::Barrier |
|
* constructs have been designed with this senario in mind). Unless |
|
* you have explicit need to set the schedule pirorites for a given |
|
* task, it is best to leave them alone. |
|
* |
|
* @note some implementations (notably LinuxThreads and IRIX Sprocs) |
|
* only alow you to decrease thread priorities dynamically. Thus, |
|
* a lower priority thread will not allow it's priority to be raised |
|
* on the fly. |
|
* |
|
* @note seting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO |
|
* will output scheduling information for each thread to stdout. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setSchedulePriority(ThreadPriority priority); |
|
|
|
/** |
|
* Get the thread's schedule priority (if able) |
|
* |
|
* @note seting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO |
|
* will output scheduling information for each thread to stdout. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int getSchedulePriority(); |
|
|
|
/** |
|
* Set the thread's scheduling policy (if able) |
|
* |
|
* @note On some implementations (notably IRIX Sprocs & LinuxThreads) |
|
* The policy may prohibit the use of SCHEDULE_ROUND_ROBIN and |
|
* SCHEDULE_FIFO policies - due to their real-time nature, and |
|
* the danger of deadlocking the machine when used as super-user. |
|
* In such cases, the command is a no-op. |
|
* |
|
* @note seting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO |
|
* will output scheduling information for each thread to stdout. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setSchedulePolicy(ThreadPolicy policy); |
|
|
|
/** |
|
* Get the thread's policy (if able) |
|
* |
|
* @note seting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO |
|
* will output scheduling information for each thread to stdout. |
|
* |
|
* @return policy if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int getSchedulePolicy(); |
|
|
|
/** |
|
* Set the thread's desired stack size (in bytes). |
|
* This method is an attribute of the thread and must be called |
|
* *before* the start() method is invoked. |
|
* |
|
* @note a return code of 13 (EACESS) means that the thread stack |
|
* size can no longer be changed. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setStackSize(size_t size); |
|
|
|
/** |
|
* Get the thread's desired stack size. |
|
* |
|
* @return the thread's stack size. 0 indicates that the stack size |
|
* has either not yet been initialized, or not yet been specified by |
|
* the application. |
|
*/ |
|
size_t getStackSize(); |
|
|
|
/** |
|
* Print the thread's scheduling information to stdout. |
|
*/ |
|
void printSchedulingInfo(); |
|
|
|
/** |
|
* Detach the thread from the calling process. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int detach(); |
|
|
|
/** |
|
* Join the calling process with the thread |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int join(); |
|
|
|
/** |
|
* Disable thread cancelation altogether. Thread::cancel() has no effect. |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setCancelModeDisable(); |
|
|
|
/** |
|
* Mark the thread to cancel aysncronously on Thread::cancel(). |
|
* (May not be available with process-level implementations). |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setCancelModeAsynchronous(); |
|
|
|
/** |
|
* Mark the thread to cancel at the earliest convenience on |
|
* Thread::cancel() (This is the default) |
|
* |
|
* @return 0 if normal, -1 if errno set, errno code otherwise. |
|
*/ |
|
int setCancelModeDeferred(); |
|
|
|
/** |
|
* Query the thread's running status |
|
* |
|
* @return true if running, false if not. |
|
*/ |
|
bool isRunning(); |
|
|
|
/** |
|
* Thread's run method. Must be implemented by derived classes. |
|
* This is where the action happens. |
|
*/ |
|
virtual void run() = 0; |
|
|
|
/** |
|
* Thread's cancel cleanup routine, called upon cancel(), after the |
|
* cancelation has taken place, but before the thread exits completely. |
|
* This method should be used to repair parts of the thread's data |
|
* that may have been damaged by a pre-mature cancel. No-op by default. |
|
*/ |
|
virtual void cancelCleanup() {}; |
|
|
|
void* getImplementation(){ return _prvData; }; |
|
|
|
/** Thread's processor affinity method. This binds a thread to a |
|
* processor whenever possible. This call must be made before |
|
* start() or startThread() and has no effect after the thread |
|
* has been running. In the pthreads implementation, this is only |
|
* implemented on sgi, through a pthread extension. On other pthread |
|
* platforms this is ignored. Returns 0 on success, implementation's |
|
* error on failure, or -1 if ignored. |
|
*/ |
|
int setProcessorAffinity( unsigned int cpunum ); |
|
|
|
/** microSleep method, equivilant to the posix usleep(microsec). |
|
* This is not strictly thread API but is used |
|
* so often with threads. It's basically UNIX usleep. Parameter is |
|
* number of microseconds we current thread to sleep. Returns 0 on |
|
* succes, non-zero on failure (UNIX errno or GetLastError() will give |
|
* detailed description. |
|
*/ |
|
static int microSleep( unsigned int microsec); |
|
|
|
private: |
|
|
|
/** |
|
* The Private Actions class is allowed to operate on private data. |
|
*/ |
|
friend class ThreadPrivateActions; |
|
|
|
/** |
|
* Private copy constructor, to prevent tampering. |
|
*/ |
|
Thread(const Thread &/*t*/) {}; |
|
|
|
/** |
|
* Private copy assignment, to prevent tampering. |
|
*/ |
|
Thread &operator=(const Thread &/*t*/) {return *(this);}; |
|
|
|
/** |
|
* Implementation-specific data |
|
*/ |
|
void * _prvData; |
|
|
|
/** |
|
* Master thread's priority, set by Thread::Init. |
|
*/ |
|
static ThreadPriority s_masterThreadPriority; |
|
|
|
/** |
|
* Is initialized flag |
|
*/ |
|
static bool s_isInitialized; |
|
}; |
|
|
|
} |
|
|
|
#endif // !_OPENTHREADS_THREAD_
|
|
|