SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thread.h
Go to the documentation of this file.
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2009 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9  License for the specific language governing rights and limitations under
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 
30 
31 ///
32 /// @file Thread.h
33 /// @brief The thread class
34 ///
35 /// @author Steve Parker
36 /// Department of Computer Science
37 /// University of Utah
38 /// @date June 1997
39 ///
40 
41 #ifndef Core_Thread_Thread_h
42 #define Core_Thread_Thread_h
43 
44 //#include <sci_defs/bits_defs.h>
51 
52 #ifndef _WIN32
53 #include <signal.h>
54 #endif
55 
56 namespace SCIRun {
57 
58 struct Thread_private;
59 class ParallelBase;
60 class Runnable;
61 class ThreadGroup;
62 
63 
64 /// The Thread class provides a new context in which to run. A single
65 /// Runnable class is attached to a single Thread class, which are
66 /// executed in another thread.
68 #ifdef SCI_64BITS
69  static const unsigned long long DEFAULT_STACKSIZE = 256 * 1024; // 256 KB
70 #else
71  static const unsigned long long DEFAULT_STACKSIZE = 128 * 1024; // 128 KB
72 #endif
73 public:
74  /// Possible thread start states
75  enum ActiveState {
78  NotActivated
79  };
80 
81  /// Create a thread, which will execute the <b>run()</b>
82  /// method in the <b>runner</b> object. The thread <b>name</b>
83  /// is used for identification purposes, and does not need to
84  /// be unique with respect to other threads. <b>Group</b>
85  /// specifies the ThreadGroup that to which this thread
86  /// should belong. If no group is specified (group==0),
87  /// the default group is used.
88  Thread(Runnable* runner,
89  const char* name,
90  ThreadGroup* group=0,
91  ActiveState state=Activated,
92  unsigned long long stack_size = DEFAULT_STACKSIZE);
93 
94 
95  /// Return the <b>ThreadGroup</b> associated with this thread.
96  ThreadGroup* getThreadGroup();
97 
98 
99  /// Return the <b>Runnable</b> associated with this thread.
100  Runnable* getRunnable();
101 
102 
103  /// Flag the thread as a daemon thread. When all non-deamon
104  /// threads exit, the program will exit.
105  void setDaemon(bool to=true);
106 
107 
108  /// Returns true if the thread is tagged as a daemon thread.
109  bool isDaemon() const;
110 
111 
112  /// If the thread is started in the the NotActivated state,
113  /// use this to activate the thread (the argument should be
114  /// false).
115  void activate(bool stopped);
116 
117 
118  /// Arrange to have the thread deleted automatically at exit.
119  /// The pointer to the thread should not be used by any other
120  /// threads once this has been called.
121  void detach();
122 
123 
124  /// Returns true if the thread is detached
125  bool isDetached() const;
126 
127 
128  /// Set the stack size for a particular thread. In order
129  /// to use this thread, you must create the thread in the
130  /// NotActivated state, set the stack size, and then start
131  /// the thread using activate(false). Setting the stack
132  /// size for a thread that is running or has ever been run,
133  /// will throw an exception. The units are in bytes.
134  void setStackSize(unsigned long long stackSize);
135 
136 
137  /// Returns the stack size for the thread
138  unsigned long long getStackSize() const;
139 
140 
141  /// Kill all threads and exit with <b>code</b>.
142  static void exitAll(int code);
143 
144 
145  /// Exit the currently running thread
146  static void exit();
147 
148 
149  /// Returns a pointer to the currently running thread.
150  static Thread* self();
151 
152 
153  /// Stop the thread.
154  void stop();
155 
156 
157  /// Resume the thread
158  void resume();
159 
160 
161  /// Blocks the calling thread until this thead has finished
162  /// executing. You cannot join detached threads or daemon threads.
163  void join();
164 
165 
166  /// Returns the name of the thread
167  const char* getThreadName() const;
168 
169 
170  /// Returns the number of processors on the system
171  static int numProcessors();
172 
173 
174  /// Request that the thread migrate to processor <i>proc</i>.
175  /// If <i>proc</i> is -1, then the thread is free to run
176  /// anywhere.
177  void migrate(int proc);
178 
179 
180  /// Start up several threads that will run in parallel. A new
181  /// <b>ThreadGroup</b> is created as a child of the optional parent.
182  /// If <i>block</i> is true, then the caller will block until all
183  /// of the threads return. Otherwise, the call will return
184  /// immediately.
185  static ThreadGroup* parallel(ParallelBase& helper,
186  int nthreads, bool block,
187  ThreadGroup* threadGroup=0);
188 
189 
190  /// Start up several threads that will run in parallel.
191  /// If <i>block</i> is true, then the caller will block until all
192  /// of the threads return. Otherwise, the call will return
193  /// immediately.
194  template<class T>
195  static void parallel(T* ptr, void (T::*pmf)(int),
196  int numThreads)
197  {
198  if (numThreads <= 1) { (ptr->*pmf)(0); }
199  else
200  {
201  Parallel<T> p(ptr, pmf);
202  parallel(p, numThreads, true);
203  }
204  }
205 
206 
207  /// Another overloaded version of parallel that passes 1 argument
208  template<class T, class Arg1>
209  static void parallel(T* ptr, void (T::*pmf)(int, Arg1),
210  int numThreads, Arg1 a1)
211  {
212  if (numThreads <= 1) { (ptr->*pmf)(0, a1); }
213  else
214  {
215  Parallel1<T, Arg1> p(ptr, pmf, a1);
216  parallel(p, numThreads, true);
217  }
218  }
219 
220 
221  /// Another overloaded version of parallel that passes 2 arguments
222  template<class T, class Arg1, class Arg2>
223  static void parallel(T* ptr, void (T::* pmf)(int, Arg1, Arg2),
224  int numThreads, Arg1 a1, Arg2 a2)
225  {
226  if (numThreads <= 1) { (ptr->*pmf)(0, a1, a2); }
227  else
228  {
229  Parallel2<T, Arg1, Arg2> p(ptr, pmf, a1, a2);
230  parallel(p, numThreads, true);
231  }
232  }
233 
234 
235  /// Another overloaded version of parallel that passes 3 arguments
236  template<class T, class Arg1, class Arg2, class Arg3>
237  static void parallel(T* ptr, void (T::* pmf)(int, Arg1, Arg2, Arg3),
238  int numThreads, Arg1 a1, Arg2 a2, Arg3 a3)
239  {
240  if (numThreads <= 1) { (ptr->*pmf)(0, a1, a2, a3); }
241  else
242  {
243  Parallel3<T, Arg1, Arg2, Arg3> p(ptr, pmf, a1, a2, a3);
244  parallel(p, numThreads, true);
245  }
246  }
247 
248  /// Another overloaded version of parallel that passes 4 arguments
249  template<class T, class Arg1, class Arg2, class Arg3, class Arg4>
250  static void parallel(T* ptr, void (T::* pmf)(int, Arg1, Arg2, Arg3, Arg4),
251  int numThreads, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4)
252  {
253  if (numThreads <= 1) { (ptr->*pmf)(0, a1, a2, a3, a4); }
254  else
255  {
256  Parallel4<T, Arg1, Arg2, Arg3, Arg4> p(ptr, pmf, a1, a2, a3, a4);
257  parallel(p, numThreads, true);
258  }
259  }
260 
261 
262  /// Abort the current thread, or the process. Prints a message on
263  /// stderr, and the user may choose one of:
264  /// <pre>continue(c)/dbx(d)/cvd(v)/kill thread(k)/exit(e)</pre>
265  /// context is necesary on Windows to catch a segfault
266  static void niceAbort(void* Context = 0);
267 
268 
269  /// Mark a section as one that could block for debugging purposes.
270  /// The <b>int</b> that is returned should be passed into
271  /// <i>couldBlockDone(int)</i> when the section has completed. This
272  /// will typically not be used outside of the thread implementation.
273  static int couldBlock(const char* why);
274 
275 
276  /// Mark the end of a selection that could block.
277  /// <i>restore</i> was returned from a previous invocation
278  /// of the above <b>couldBlock</b>.
279  static void couldBlockDone(int restore);
280 
281 
282  /// The calling process voluntarily gives up time to another process
283  static void yield();
284 
285 
286  /// Return true if the thread library has been initialized. This
287  /// will typically not be used outside of the thread implementation.
288  static bool isInitialized();
289 
290  /// set to "exit" (or something else) so we don't have to always
291  /// wait for the user to input something
292  static void setDefaultAbortMode(const char* abortMode);
293 
294  static void initialize();
295 
296  friend class Runnable;
297  friend class ConditionVariable;
298  friend class RecursiveMutex;
299  friend class Mutex;
300  friend struct Thread_private;
301  friend class SystemCallManager;
302 
303  friend void Thread_run(Thread* t);
304  friend void Thread_shutdown(Thread*,bool);
305 #ifdef _WIN32
306  friend unsigned long run_threads(void* priv_v);
307 #else
308  friend void* run_threads(void* priv_v);
309  friend void handle_abort_signals(int, siginfo_t*, void*);
310  friend void handle_quit(int);
311  friend void handle_siguser2(int);
312  friend void install_signal_handlers();
313  friend void exit_handler();
314 #endif
315 
316 private:
317 
318  Runnable* runner_;
319  const char* threadname_;
320  ThreadGroup* group_;
321  unsigned long long stacksize_;
322  bool daemon_;
323  bool detached_;
324  bool activated_;
325 
326  void os_start(bool stopped);
327  Thread(ThreadGroup* g, const char* name);
328 
329  static bool initialized;
330  static void checkExit();
331 
332  static const char* defaultAbortMode;
333  int cpu_;
334  ~Thread();
335 
336  Thread_private* priv_;
337 
338  static int id();
339  void run_body();
340  enum ThreadState {
341  STARTUP,
342  RUNNING,
343  IDLE,
344  SHUTDOWN,
345  DIED,
346  PROGRAM_EXIT,
347  JOINING,
348  BLOCK_ANY,
349  BLOCK_BARRIER,
350  BLOCK_MUTEX,
351  BLOCK_SEMAPHORE,
352  BLOCK_CONDITIONVARIABLE
353  };
354 
355  static const char* getStateString(ThreadState);
356 
357  static int push_bstack(Thread_private*, Thread::ThreadState s, const char* why);
358  static void pop_bstack(Thread_private*, int oldstate);
359 
360  static void print_threads();
361 
362  /// Cannot copy them
363  Thread(const Thread&);
364  Thread& operator=(const Thread&);
365 };
366 } // End namespace SCIRun
367 
368 #endif
369 
370 
void Thread_run(Thread *t)
Definition: Thread_pthreads.cc:377
static void parallel(T *ptr, void(T::*pmf)(int, Arg1), int numThreads, Arg1 a1)
Another overloaded version of parallel that passes 1 argument.
Definition: Thread.h:209
void exit_handler()
Definition: Thread_pthreads.cc:722
Definition: Thread.h:67
static void parallel(T *ptr, void(T::*pmf)(int, Arg1, Arg2), int numThreads, Arg1 a1, Arg2 a2)
Another overloaded version of parallel that passes 2 arguments.
Definition: Thread.h:223
void handle_quit(int sig)
Definition: Thread_pthreads.cc:609
Definition: RecursiveMutex.h:68
#define SCISHARE
Definition: share.h:39
Definition: ParallelBase.h:62
Definition: ConditionVariable.h:80
Definition: Parallel3.h:61
void Thread_shutdown(Thread *thread, bool)
Definition: Thread_pthreads.cc:228
Definition: Parallel1.h:61
Definition: Mutex.h:65
Automatically instantiate several threads, with 2 arguments.
const char * name[]
Definition: BoostGraphExampleTests.cc:87
Definition: Parallel4.h:61
Definition: Parallel2.h:61
Definition: Parallel.h:61
Definition: Thread_pthreads.cc:112
void handle_siguser2(int)
Definition: Thread_pthreads.cc:648
static void parallel(T *ptr, void(T::*pmf)(int, Arg1, Arg2, Arg3, Arg4), int numThreads, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4)
Another overloaded version of parallel that passes 4 arguments.
Definition: Thread.h:250
Automatically instantiate several threads, with 1 argument.
ActiveState
Possible thread start states.
Definition: Thread.h:75
void * run_threads(void *priv_v)
Definition: Thread_pthreads.cc:383
void handle_abort_signals(int sig, siginfo_t *info, void *)
Definition: Thread_pthreads.cc:537
Automatically instantiate several threads, with 4 arguments.
static void parallel(T *ptr, void(T::*pmf)(int), int numThreads)
Definition: Thread.h:195
Definition: ThreadGroup.h:68
Definition: Thread.h:76
Definition: Thread.h:77
static void parallel(T *ptr, void(T::*pmf)(int, Arg1, Arg2, Arg3), int numThreads, Arg1 a1, Arg2 a2, Arg3 a3)
Another overloaded version of parallel that passes 3 arguments.
Definition: Thread.h:237