Panda3D
threadSimpleImpl.h
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 threadSimpleImpl.h
10  * @author drose
11  * @date 2007-06-18
12  */
13 
14 #ifndef THREADSIMPLEIMPL_H
15 #define THREADSIMPLEIMPL_H
16 
17 #include "pandabase.h"
18 #include "selectThreadImpl.h"
19 
20 #ifdef THREAD_SIMPLE_IMPL
21 
22 #include "pnotify.h"
23 #include "threadPriority.h"
24 #include "pvector.h"
25 #include "contextSwitch.h"
26 
27 class Thread;
28 class ThreadSimpleManager;
29 class MutexSimpleImpl;
30 
31 /**
32  * This is a trivial threading implementation for applications that don't
33  * desire full OS-managed threading. It is a user-space implementation of
34  * threads implemented via setjmp/longjmp, and therefore it cannot take
35  * advantage of multiple CPU's (the application will always run on a single
36  * CPU, regardless of the number of threads you spawn).
37  *
38  * However, since context switching is entirely cooperative, synchronization
39  * primitives like mutexes and condition variables aren't necessary, and the
40  * Mutex and ConditionVar classes are compiled into trivial no-op classes,
41  * which can reduce overhead substantially compared to a truly threaded
42  * application.
43  *
44  * Be sure that every thread calls Thread::consider_yield() occasionally, or
45  * it will starve the rest of the running threads.
46  */
47 class EXPCL_PANDA_PIPELINE ThreadSimpleImpl {
48 public:
49  ThreadSimpleImpl(Thread *parent_obj);
50  ~ThreadSimpleImpl();
51 
52  void setup_main_thread();
53  bool start(ThreadPriority priority, bool joinable);
54  void join();
55  void preempt();
56 
57  std::string get_unique_id() const;
58 
59  static void prepare_for_exit();
60 
61  INLINE static Thread *get_current_thread();
62  INLINE bool is_same_system_thread() const;
63 
64  INLINE static void bind_thread(Thread *thread);
65  INLINE static bool is_threading_supported();
66  static bool is_true_threads();
67  INLINE static bool is_simple_threads();
68  INLINE static void sleep(double seconds);
69  INLINE static void yield();
70  INLINE static void consider_yield();
71 
72  void sleep_this(double seconds);
73  void yield_this(bool volunteer);
74  INLINE void consider_yield_this();
75 
76  INLINE double get_wake_time() const;
77 
78  INLINE static void write_status(std::ostream &out);
79 
80 private:
81  static void st_begin_thread(void *data);
82  void begin_thread();
83 
84 private:
85  enum ThreadStatus {
86  TS_new,
87  TS_running,
88  TS_finished,
89  TS_killed,
90  };
91 
92  static int _next_unique_id;
93  int _unique_id;
94  Thread *_parent_obj;
95  bool _joinable;
96  ThreadStatus _status;
97  ThreadPriority _priority;
98 
99  // The relative weight of this thread, relative to other threads, in
100  // priority.
101  double _priority_weight;
102 
103  // The amount of time this thread has run recently.
104  unsigned int _run_ticks;
105 
106  // This is the time at which the currently-running thread started execution.
107  double _start_time;
108 
109  // This is the time at which the currently-running thread should yield.
110  double _stop_time;
111 
112  // This records the time at which a sleeping thread should wake up.
113  double _wake_time;
114 
115  ThreadContext *_context;
116  unsigned char *_stack;
117  size_t _stack_size;
118 
119 #ifdef HAVE_PYTHON
120  // If we might be working with Python, we have to manage the Python thread
121  // state as we switch contexts.
122  PyThreadState *_python_state;
123 #endif // HAVE_PYTHON
124 
125  // Threads that are waiting for this thread to finish.
126  typedef pvector<ThreadSimpleImpl *> JoiningThreads;
127  JoiningThreads _joining_threads;
128 
129  ThreadSimpleManager *_manager;
130  static ThreadSimpleImpl *volatile _st_this;
131 
132  // We may not mix-and-match OS threads with Panda's SIMPLE_THREADS. If we
133  // ever get a Panda context switch request from a different OS thread than
134  // the thread we think we should be in, that's a serious error that may
135  // cause major consequences. For this reason, we store the OS thread's
136  // current thread ID here when the thread is constructed, and insist that it
137  // never changes during the lifetime of the thread.
138 #ifdef HAVE_POSIX_THREADS
139  pthread_t _posix_system_thread_id;
140 #endif
141 #ifdef WIN32
142  DWORD _win32_system_thread_id;
143 #endif
144 
145  friend class ThreadSimpleManager;
146 };
147 
148 // We include this down here to avoid the circularity problem.
149 /* okcircular */
150 #include "threadSimpleManager.h"
151 
152 #include "threadSimpleImpl.I"
153 
154 #endif // THREAD_SIMPLE_IMPL
155 
156 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
Definition: thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.