Thread 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /* -*-c++-*- OpenThreads library, Copyright (C) 2002 - 2007 The Open Thread Group
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. //
  14. // Thread - C++ Thread class
  15. // ~~~~~~~~
  16. //
  17. #ifndef _OPENTHREADS_THREAD_
  18. #define _OPENTHREADS_THREAD_
  19. #include <sys/types.h>
  20. #include <OpenThreads/Mutex>
  21. #include <OpenThreads/Affinity>
  22. namespace OpenThreads {
  23. /**
  24. * Get the number of processors.
  25. *
  26. * Note, systems where no support exists for querying the number of processors, 1 is returned.
  27. *
  28. */
  29. extern OPENTHREAD_EXPORT_DIRECTIVE int GetNumberOfProcessors();
  30. /**
  31. * Set the processor affinity of current thread.
  32. */
  33. extern OPENTHREAD_EXPORT_DIRECTIVE int SetProcessorAffinityOfCurrentThread(const Affinity& affinity);
  34. /**
  35. * @class Thread
  36. * @brief This class provides an object-oriented thread interface.
  37. */
  38. class OPENTHREAD_EXPORT_DIRECTIVE Thread {
  39. public:
  40. /**
  41. * Set the concurrency level for a running application. This method
  42. * only has effect if the pthreads thread model is being used, and
  43. * then only when that model is many-to-one (eg. irix).
  44. * in other cases it is ignored. The concurrency level is only a
  45. * *hint* as to the number of execution vehicles to use, the actual
  46. * implementation may do anything it wants. Setting the value
  47. * to 0 returns things to their default state.
  48. *
  49. * @return previous concurrency level, -1 indicates no-op.
  50. */
  51. static int SetConcurrency(int concurrencyLevel);
  52. /**
  53. * Get the concurrency level for a running application. In this
  54. * case, a return code of 0 means that the application is in default
  55. * mode. A return code of -1 means that the application is incapable
  56. * of setting an arbitrary concurrency, because it is a one-to-one
  57. * execution model (sprocs, linuxThreads)
  58. */
  59. static int GetConcurrency();
  60. /**
  61. * Enumerated Type for thread priority
  62. */
  63. enum ThreadPriority {
  64. THREAD_PRIORITY_MAX, /**< The maximum possible priority */
  65. THREAD_PRIORITY_HIGH, /**< A high (but not max) setting */
  66. THREAD_PRIORITY_NOMINAL, /**< An average priority */
  67. THREAD_PRIORITY_LOW, /**< A low (but not min) setting */
  68. THREAD_PRIORITY_MIN, /**< The miniumum possible priority */
  69. THREAD_PRIORITY_DEFAULT /**< Priority scheduling default */
  70. };
  71. /**
  72. * Enumerated Type for thread scheduling policy
  73. */
  74. enum ThreadPolicy {
  75. THREAD_SCHEDULE_FIFO, /**< First in, First out scheduling */
  76. THREAD_SCHEDULE_ROUND_ROBIN, /**< Round-robin scheduling (LINUX_DEFAULT) */
  77. THREAD_SCHEDULE_TIME_SHARE, /**< Time-share scheduling (IRIX DEFAULT) */
  78. THREAD_SCHEDULE_DEFAULT /**< Default scheduling */
  79. };
  80. /**
  81. * Constructor
  82. */
  83. Thread();
  84. /**
  85. * Destructor
  86. */
  87. virtual ~Thread();
  88. /**
  89. * Return a pointer to the current running thread, returns NULL for a non OpenThreads thread.
  90. */
  91. static Thread *CurrentThread();
  92. /**
  93. * Return the id of the current thread
  94. */
  95. static size_t CurrentThreadId();
  96. /**
  97. * Initialize Threading in a program. This method must be called before
  98. * you can do any threading in a program.
  99. */
  100. static void Init();
  101. /**
  102. * Yield the processor.
  103. *
  104. * @note This method operates on the calling process. And is
  105. * equivalent to calling sched_yield().
  106. *
  107. * @return 0 if normal, -1 if errno set, errno code otherwise.
  108. */
  109. static int YieldCurrentThread();
  110. /**
  111. * This method will return the ThreadPriority of the master process.
  112. * (ie, the one calling the thread->start() methods for the first time)
  113. * The method will almost certainly return
  114. * Thread::THREAD_PRIORITY_DEFAULT if
  115. * Init() has not been called.
  116. *
  117. * @return the Thread::ThreadPriority of the master thread.
  118. */
  119. static ThreadPriority GetMasterPriority() {return s_masterThreadPriority;};
  120. /**
  121. * Get a unique thread id. This id is monotonically increasing.
  122. *
  123. * @return a unique thread identifier
  124. */
  125. size_t getThreadId();
  126. /**
  127. * Get the thread's process id. This is the pthread_t or pid_t value
  128. * depending on the threading model being used.
  129. *
  130. * @return thread process id.
  131. */
  132. size_t getProcessId();
  133. /**
  134. * Start the thread. This method will configure the thread, set
  135. * it's priority, and spawn it.
  136. *
  137. * @note if the stack size specified setStackSize is smaller than the
  138. * smallest allowable stack size, the threads stack size will be set to
  139. * the minimum allowed, and may be retrieved via the getStackSize()
  140. *
  141. * @return 0 if normal, -1 if errno set, errno code otherwise.
  142. */
  143. int start();
  144. int startThread();
  145. /**
  146. * Test the cancel state of the thread. If the thread has been canceled
  147. * this method will cause the thread to exit now. This method operates
  148. * on the calling thread.
  149. *
  150. * Returns 0 if normal, -1 if called from a thread other that this.
  151. */
  152. int testCancel();
  153. /**
  154. * Cancel the thread. Equivalent to SIGKILL.
  155. *
  156. * @return 0 if normal, -1 if errno set, errno code otherwise.
  157. */
  158. virtual int cancel();
  159. /**
  160. * Set the thread's schedule priority. This is a complex method.
  161. * Beware of thread priorities when using a many-to-many kernel
  162. * entity implementation (such as IRIX pthreads). If one is not careful
  163. * to manage the thread priorities, a priority inversion deadlock can
  164. * easily occur (Although the OpenThreads::Mutex & OpenThreads::Barrier
  165. * constructs have been designed with this scenario in mind). Unless
  166. * you have explicit need to set the schedule priorities for a given
  167. * task, it is best to leave them alone.
  168. *
  169. * @note some implementations (notably LinuxThreads and IRIX Sprocs)
  170. * only allow you to decrease thread priorities dynamically. Thus,
  171. * a lower priority thread will not allow it's priority to be raised
  172. * on the fly.
  173. *
  174. * @note setting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO
  175. * will output scheduling information for each thread to stdout.
  176. *
  177. * @return 0 if normal, -1 if errno set, errno code otherwise.
  178. */
  179. int setSchedulePriority(ThreadPriority priority);
  180. /**
  181. * Get the thread's schedule priority (if able)
  182. *
  183. * @note setting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO
  184. * will output scheduling information for each thread to stdout.
  185. *
  186. * @return 0 if normal, -1 if errno set, errno code otherwise.
  187. */
  188. int getSchedulePriority();
  189. /**
  190. * Set the thread's scheduling policy (if able)
  191. *
  192. * @note On some implementations (notably IRIX Sprocs & LinuxThreads)
  193. * The policy may prohibit the use of SCHEDULE_ROUND_ROBIN and
  194. * SCHEDULE_FIFO policies - due to their real-time nature, and
  195. * the danger of deadlocking the machine when used as super-user.
  196. * In such cases, the command is a no-op.
  197. *
  198. * @note setting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO
  199. * will output scheduling information for each thread to stdout.
  200. *
  201. * @return 0 if normal, -1 if errno set, errno code otherwise.
  202. */
  203. int setSchedulePolicy(ThreadPolicy policy);
  204. /**
  205. * Get the thread's policy (if able)
  206. *
  207. * @note setting the environment variable OUTPUT_THREADLIB_SCHEDULING_INFO
  208. * will output scheduling information for each thread to stdout.
  209. *
  210. * @return policy if normal, -1 if errno set, errno code otherwise.
  211. */
  212. int getSchedulePolicy();
  213. /**
  214. * Set the thread's desired stack size (in bytes).
  215. * This method is an attribute of the thread and must be called
  216. * *before* the start() method is invoked.
  217. *
  218. * @note a return code of 13 (EACESS) means that the thread stack
  219. * size can no longer be changed.
  220. *
  221. * @return 0 if normal, -1 if errno set, errno code otherwise.
  222. */
  223. int setStackSize(size_t size);
  224. /**
  225. * Get the thread's desired stack size.
  226. *
  227. * @return the thread's stack size. 0 indicates that the stack size
  228. * has either not yet been initialized, or not yet been specified by
  229. * the application.
  230. */
  231. size_t getStackSize();
  232. /**
  233. * Print the thread's scheduling information to stdout.
  234. */
  235. void printSchedulingInfo();
  236. /**
  237. * Detach the thread from the calling process.
  238. *
  239. * @return 0 if normal, -1 if errno set, errno code otherwise.
  240. */
  241. int detach();
  242. /**
  243. * Join the calling process with the thread
  244. *
  245. * @return 0 if normal, -1 if errno set, errno code otherwise.
  246. */
  247. int join();
  248. /**
  249. * Disable thread cancellation altogether. Thread::cancel() has no effect.
  250. *
  251. * @return 0 if normal, -1 if errno set, errno code otherwise.
  252. */
  253. int setCancelModeDisable();
  254. /**
  255. * Mark the thread to cancel asynchronously on Thread::cancel().
  256. * (May not be available with process-level implementations).
  257. *
  258. * @return 0 if normal, -1 if errno set, errno code otherwise.
  259. */
  260. int setCancelModeAsynchronous();
  261. /**
  262. * Mark the thread to cancel at the earliest convenience on
  263. * Thread::cancel() (This is the default)
  264. *
  265. * @return 0 if normal, -1 if errno set, errno code otherwise.
  266. */
  267. int setCancelModeDeferred();
  268. /**
  269. * Query the thread's running status
  270. *
  271. * @return true if running, false if not.
  272. */
  273. bool isRunning();
  274. /**
  275. * Thread's run method. Must be implemented by derived classes.
  276. * This is where the action happens.
  277. */
  278. virtual void run() = 0;
  279. /**
  280. * Thread's cancel cleanup routine, called upon cancel(), after the
  281. * cancellation has taken place, but before the thread exits completely.
  282. * This method should be used to repair parts of the thread's data
  283. * that may have been damaged by a pre-mature cancel. No-op by default.
  284. */
  285. virtual void cancelCleanup() {};
  286. void* getImplementation(){ return _prvData; };
  287. /** Set the Thread's processor affinity to all, a single CPU or multiple CPU's
  288. * This call must be made before
  289. * start() or startThread() and has no effect after the thread
  290. * has been running. Returns 0 on success, implementation's
  291. * error on failure, or -1 if ignored.
  292. */
  293. int setProcessorAffinity( const Affinity& affinity);
  294. /** microSleep method, equivalent to the posix usleep(microsec).
  295. * This is not strictly thread API but is used
  296. * so often with threads. It's basically UNIX usleep. Parameter is
  297. * number of microseconds we current thread to sleep. Returns 0 on
  298. * success, non-zero on failure (UNIX errno or GetLastError() will give
  299. * detailed description.
  300. */
  301. static int microSleep( unsigned int microsec);
  302. private:
  303. /**
  304. * The Private Actions class is allowed to operate on private data.
  305. */
  306. friend class ThreadPrivateActions;
  307. /**
  308. * Private copy constructor, to prevent tampering.
  309. */
  310. Thread(const Thread &/*t*/) {};
  311. /**
  312. * Private copy assignment, to prevent tampering.
  313. */
  314. Thread &operator=(const Thread &/*t*/) {return *(this);};
  315. /**
  316. * Implementation-specific data
  317. */
  318. void * _prvData;
  319. /**
  320. * Master thread's priority, set by Thread::Init.
  321. */
  322. static ThreadPriority s_masterThreadPriority;
  323. /**
  324. * Is initialized flag
  325. */
  326. static bool s_isInitialized;
  327. };
  328. }
  329. #endif // !_OPENTHREADS_THREAD_