Panda3D
thread.I
1 // Filename: thread.I
2 // Created by: drose (08Aug02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: Thread::Copy Constructor
18 // Access: Private
19 // Description: Do not attempt to copy threads.
20 ////////////////////////////////////////////////////////////////////
21 INLINE Thread::
22 Thread(const Thread &copy) : _impl(this) {
23  nassertv(false);
24 }
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: Thread::Copy Assignment Operator
28 // Access: Private
29 // Description: Do not attempt to copy threads.
30 ////////////////////////////////////////////////////////////////////
31 INLINE void Thread::
32 operator = (const Thread &copy) {
33  nassertv(false);
34 }
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: Thread::get_sync_name
38 // Access: Published
39 // Description: Returns the sync name of the thread. This name
40 // collects threads into "sync groups", which are
41 // expected to run synchronously. This is mainly used
42 // for the benefit of PStats; threads with the same sync
43 // name can be ticked all at once via the thread_tick()
44 // call.
45 ////////////////////////////////////////////////////////////////////
46 INLINE const string &Thread::
47 get_sync_name() const {
48  return _sync_name;
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: Thread::get_pstats_index
53 // Access: Published
54 // Description: Returns the PStats index associated with this thread,
55 // or -1 if no index has yet been associated with this
56 // thread. This is used internally by the PStatClient;
57 // you should not need to call this directly.
58 ////////////////////////////////////////////////////////////////////
59 INLINE int Thread::
61  return _pstats_index;
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: Thread::get_unique_id
66 // Access: Published
67 // Description: Returns a string that is guaranteed to be unique to
68 // this thread, across all processes on the machine,
69 // during at least the lifetime of this process.
70 ////////////////////////////////////////////////////////////////////
71 INLINE string Thread::
72 get_unique_id() const {
73  return _impl.get_unique_id();
74 }
75 
76 ////////////////////////////////////////////////////////////////////
77 // Function: Thread::get_pipeline_stage
78 // Access: Published
79 // Description: Returns the Pipeline stage number associated with
80 // this thread. The default stage is 0 if no stage is
81 // specified otherwise. See set_pipeline_stage().
82 ////////////////////////////////////////////////////////////////////
83 INLINE int Thread::
85  return _pipeline_stage;
86 }
87 
88 ////////////////////////////////////////////////////////////////////
89 // Function: Thread::set_min_pipeline_stage
90 // Access: Published
91 // Description: Sets this thread's pipeline stage number to at least
92 // the indicated value, unless it is already larger.
93 // See set_pipeline_stage().
94 ////////////////////////////////////////////////////////////////////
95 INLINE void Thread::
96 set_min_pipeline_stage(int min_pipeline_stage) {
97  set_pipeline_stage(max(_pipeline_stage, min_pipeline_stage));
98 }
99 
100 ////////////////////////////////////////////////////////////////////
101 // Function: Thread::get_main_thread
102 // Access: Published, Static
103 // Description: Returns a pointer to the "main" Thread object--this
104 // is the Thread that started the whole process.
105 ////////////////////////////////////////////////////////////////////
106 INLINE Thread *Thread::
108  if (_main_thread == (Thread *)NULL) {
109  init_main_thread();
110  }
111  return _main_thread;
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: Thread::get_external_thread
116 // Access: Published, Static
117 // Description: Returns a pointer to the "external" Thread
118 // object--this is a special Thread object that
119 // corresponds to any thread spawned outside of Panda's
120 // threading interface. Note that multiple different
121 // threads may share this same pointer.
122 ////////////////////////////////////////////////////////////////////
123 INLINE Thread *Thread::
125  if (_external_thread == (Thread *)NULL) {
126  init_external_thread();
127  }
128  return _external_thread;
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: Thread::get_current_thread
133 // Access: Published, Static
134 // Description: Returns a pointer to the currently-executing Thread
135 // object. If this is called from the main thread, this
136 // will return the same value as get_main_thread().
137 //
138 // This will always return some valid Thread pointer.
139 // It will never return NULL, even if the current thread
140 // was spawned outside of Panda's threading system,
141 // although all non-Panda threads will return the exact
142 // same Thread pointer.
143 ////////////////////////////////////////////////////////////////////
144 INLINE Thread *Thread::
146  TAU_PROFILE("Thread *Thread::get_current_thread()", " ", TAU_USER);
147 #ifndef HAVE_THREADS
148  return get_main_thread();
149 #else // HAVE_THREADS
150  Thread *thread = ThreadImpl::get_current_thread();
151  if (thread == (Thread *)NULL) {
153  }
154  return thread;
155 #endif // HAVE_THREADS
156 }
157 
158 ////////////////////////////////////////////////////////////////////
159 // Function: Thread::get_current_pipeline_stage
160 // Access: Published, Static
161 // Description: Returns the integer pipeline stage associated with
162 // the current thread. This is the same thing as
163 // get_current_thread()->get_pipeline_stage(), but it
164 // may be faster to retrieve in some contexts.
165 ////////////////////////////////////////////////////////////////////
166 INLINE int Thread::
168  TAU_PROFILE("int Thread::get_current_pipeline_stage()", " ", TAU_USER);
169 #ifndef THREADED_PIPELINE
170  // Without threaded pipelining, the result is always 0.
171  return 0;
172 #else
174 #endif // !THREADED_PIPELINE
175 }
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function: Thread::is_threading_supported
179 // Access: Published, Static
180 // Description: Returns true if threading support has been compiled
181 // in and enabled, or false if no threading is available
182 // (and Thread::start() will always fail).
183 ////////////////////////////////////////////////////////////////////
184 INLINE bool Thread::
186  if (!support_threads) {
187  return false;
188  }
189  return ThreadImpl::is_threading_supported();
190 }
191 
192 ////////////////////////////////////////////////////////////////////
193 // Function: Thread::is_true_threads
194 // Access: Published, Static
195 // Description: Returns true if a real threading library is available
196 // that supports actual OS-implemented threads, or false
197 // if the only threading we can provide is simulated
198 // user-space threading.
199 ////////////////////////////////////////////////////////////////////
200 INLINE bool Thread::
202  if (!support_threads) {
203  return false;
204  }
205  return ThreadImpl::is_true_threads();
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: Thread::is_simple_threads
210 // Access: Published, Static
211 // Description: Returns true if Panda is currently compiled for
212 // "simple threads", which is to say, cooperative
213 // context switching only, reducing the need for quite
214 // so many critical section protections. This is not
215 // necessarily the opposite of "true threads", since one
216 // possible implementation of simple threads is via true
217 // threads with mutex protection to ensure only one runs
218 // at a time.
219 ////////////////////////////////////////////////////////////////////
220 INLINE bool Thread::
222  if (!support_threads) {
223  return false;
224  }
225  return ThreadImpl::is_simple_threads();
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: Thread::sleep
230 // Access: Published, Static
231 // Description: Suspends the current thread for at least the
232 // indicated amount of time. It might be suspended for
233 // longer.
234 ////////////////////////////////////////////////////////////////////
235 INLINE void Thread::
236 sleep(double seconds) {
237  TAU_PROFILE("void Thread::sleep(double)", " ", TAU_USER);
238  ThreadImpl::sleep(seconds);
239 }
240 
241 ////////////////////////////////////////////////////////////////////
242 // Function: Thread::field_yield
243 // Access: Published, Static
244 // Description: Suspends the current thread for the rest of the
245 // current epoch.
246 ////////////////////////////////////////////////////////////////////
247 INLINE void Thread::
249  TAU_PROFILE("void Thread::yield()", " ", TAU_USER);
250  ThreadImpl::yield();
251 }
252 
253 ////////////////////////////////////////////////////////////////////
254 // Function: Thread::consider_yield
255 // Access: Published, Static
256 // Description: Possibly suspends the current thread for the rest of
257 // the current epoch, if it has run for enough this
258 // epoch. This is especially important for the simple
259 // thread implementation, which relies on cooperative
260 // yields like this.
261 ////////////////////////////////////////////////////////////////////
262 INLINE void Thread::
264  TAU_PROFILE("void Thread::consider_yield()", " ", TAU_USER);
265  ThreadImpl::consider_yield();
266 }
267 
268 ////////////////////////////////////////////////////////////////////
269 // Function: Thread::is_started
270 // Access: Published
271 // Description: Returns true if the thread has been started, false if
272 // it has not, or if join() has already been called.
273 ////////////////////////////////////////////////////////////////////
274 INLINE bool Thread::
275 is_started() const {
276  return _started;
277 }
278 
279 ////////////////////////////////////////////////////////////////////
280 // Function: Thread::is_joinable
281 // Access: Published
282 // Description: Returns the value of joinable that was passed to the
283 // start() call.
284 ////////////////////////////////////////////////////////////////////
285 INLINE bool Thread::
286 is_joinable() const {
287  return _joinable;
288 }
289 
290 ////////////////////////////////////////////////////////////////////
291 // Function: Thread::join
292 // Access: Published
293 // Description: Blocks the calling process until the thread
294 // terminates. If the thread has already terminated,
295 // this returns immediately.
296 ////////////////////////////////////////////////////////////////////
297 INLINE void Thread::
298 join() {
299  TAU_PROFILE("void Thread::join()", " ", TAU_USER);
300  if (_started) {
301  _impl.join();
302  _started = false;
303  }
304 }
305 
306 ////////////////////////////////////////////////////////////////////
307 // Function: Thread::preempt
308 // Access: Published
309 // Description: Indicates that this thread should run as soon as
310 // possible, preemptying any other threads that may be
311 // scheduled to run. This may not be implemented on
312 // every platform.
313 ////////////////////////////////////////////////////////////////////
314 INLINE void Thread::
316  if (_started) {
317  _impl.preempt();
318  }
319 }
320 
321 ////////////////////////////////////////////////////////////////////
322 // Function: Thread::get_current_task
323 // Access: Published
324 // Description: Returns the task currently executing on this thread
325 // (via the AsyncTaskManager), if any, or NULL if the
326 // thread is not currently servicing a task.
327 ////////////////////////////////////////////////////////////////////
328 INLINE AsyncTaskBase *Thread::
330  return _current_task;
331 }
332 
333 ////////////////////////////////////////////////////////////////////
334 // Function: Thread::prepare_for_exit
335 // Access: Published
336 // Description: Should be called by the main thread just before
337 // exiting the program, this blocks until any remaining
338 // thread cleanup has finished.
339 ////////////////////////////////////////////////////////////////////
340 INLINE void Thread::
342  ThreadImpl::prepare_for_exit();
343 }
344 
345 ////////////////////////////////////////////////////////////////////
346 // Function: Thread::set_pstats_index
347 // Access: Public
348 // Description: Stores a PStats index to be associated with this
349 // thread. This is used internally by the PStatClient;
350 // you should not need to call this directly.
351 ////////////////////////////////////////////////////////////////////
352 INLINE void Thread::
353 set_pstats_index(int pstats_index) {
354  _pstats_index = pstats_index;
355 }
356 
357 ////////////////////////////////////////////////////////////////////
358 // Function: Thread::set_pstats_callback
359 // Access: Public
360 // Description: Stores a PStats callback to be associated with this
361 // thread. This is used internally by the PStatClient;
362 // you should not need to call this directly.
363 ////////////////////////////////////////////////////////////////////
364 INLINE void Thread::
366  _pstats_callback = pstats_callback;
367 }
368 
369 ////////////////////////////////////////////////////////////////////
370 // Function: Thread::get_pstats_callback
371 // Access: Public
372 // Description: Returns the PStats callback associated with this thread,
373 // or NULL if no callback has yet been associated with
374 // this thread. This is used internally by the
375 // PStatClient; you should not need to call this
376 // directly.
377 ////////////////////////////////////////////////////////////////////
380  return _pstats_callback;
381 }
382 
383 INLINE ostream &
384 operator << (ostream &out, const Thread &thread) {
385  thread.output(out);
386  return out;
387 }
void set_pstats_index(int pstats_index)
Stores a PStats index to be associated with this thread.
Definition: thread.I:353
bool is_started() const
Returns true if the thread has been started, false if it has not, or if join() has already been calle...
Definition: thread.I:275
The abstract base class for AsyncTask.
Definition: asyncTaskBase.h:31
int get_pipeline_stage() const
Returns the Pipeline stage number associated with this thread.
Definition: thread.I:84
void set_min_pipeline_stage(int min_pipeline_stage)
Sets this thread&#39;s pipeline stage number to at least the indicated value, unless it is already larger...
Definition: thread.I:96
static bool is_true_threads()
Returns true if a real threading library is available that supports actual OS-implemented threads...
Definition: thread.I:201
AsyncTaskBase * get_current_task() const
Returns the task currently executing on this thread (via the AsyncTaskManager), if any...
Definition: thread.I:329
static void prepare_for_exit()
Should be called by the main thread just before exiting the program, this blocks until any remaining ...
Definition: thread.I:341
static Thread * get_external_thread()
Returns a pointer to the "external" Thread object–this is a special Thread object that corresponds t...
Definition: thread.I:124
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
Definition: thread.I:263
static void force_yield()
Suspends the current thread for the rest of the current epoch.
Definition: thread.I:248
PStatsCallback * get_pstats_callback() const
Returns the PStats callback associated with this thread, or NULL if no callback has yet been associat...
Definition: thread.I:379
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
int get_pstats_index() const
Returns the PStats index associated with this thread, or -1 if no index has yet been associated with ...
Definition: thread.I:60
void preempt()
Indicates that this thread should run as soon as possible, preemptying any other threads that may be ...
Definition: thread.I:315
static Thread * get_main_thread()
Returns a pointer to the "main" Thread object–this is the Thread that started the whole process...
Definition: thread.I:107
const string & get_sync_name() const
Returns the sync name of the thread.
Definition: thread.I:47
static bool is_threading_supported()
Returns true if threading support has been compiled in and enabled, or false if no threading is avail...
Definition: thread.I:185
void set_pipeline_stage(int pipeline_stage)
Specifies the Pipeline stage number associated with this thread.
Definition: thread.cxx:158
static bool is_simple_threads()
Returns true if Panda is currently compiled for "simple threads", which is to say, cooperative context switching only, reducing the need for quite so many critical section protections.
Definition: thread.I:221
void set_pstats_callback(PStatsCallback *pstats_callback)
Stores a PStats callback to be associated with this thread.
Definition: thread.I:365
bool is_joinable() const
Returns the value of joinable that was passed to the start() call.
Definition: thread.I:286
static void sleep(double seconds)
Suspends the current thread for at least the indicated amount of time.
Definition: thread.I:236
void join()
Blocks the calling process until the thread terminates.
Definition: thread.I:298
A thread; that is, a lightweight process.
Definition: thread.h:51
string get_unique_id() const
Returns a string that is guaranteed to be unique to this thread, across all processes on the machine...
Definition: thread.I:72
static int get_current_pipeline_stage()
Returns the integer pipeline stage associated with the current thread.
Definition: thread.I:167