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