Panda3D
threadSimpleManager.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 threadSimpleManager.h
10  * @author drose
11  * @date 2007-06-18
12  */
13 
14 #ifndef THREADSIMPLEMANAGER_H
15 #define THREADSIMPLEMANAGER_H
16 
17 #include "pandabase.h"
18 #include "selectThreadImpl.h"
19 
20 #ifdef THREAD_SIMPLE_IMPL
21 
22 #include "pdeque.h"
23 #include "pmap.h"
24 #include "pvector.h"
25 #include "trueClock.h"
26 #include "configVariableDouble.h"
27 #include <algorithm>
28 
29 #ifdef HAVE_POSIX_THREADS
30 #include <pthread.h> // for pthread_t, below
31 #endif
32 #ifdef WIN32
33 #ifndef WIN32_LEAN_AND_MEAN
34 #define WIN32_LEAN_AND_MEAN 1
35 #endif
36 #include <windows.h> // for DWORD, below
37 #endif
38 
39 class Thread;
40 class ThreadSimpleImpl;
41 class BlockerSimple;
42 struct ThreadContext;
43 
44 /**
45  * This is the global object that selects the currently-active thread of the
46  * various ThreadSimpleImpl objects running, when the currently-active thread
47  * yields.
48  *
49  * This class only exists when we are using the ThreadSimple implementation,
50  * which is to say, we are not using "real" threads.
51  *
52  * Generally, you shouldn't be calling these methods directly. Call the
53  * interfaces on Thread instead.
54  */
55 class EXPCL_PANDA_PIPELINE ThreadSimpleManager {
56 private:
57  ThreadSimpleManager();
58 
59 public:
60  void enqueue_ready(ThreadSimpleImpl *thread, bool volunteer);
61  void enqueue_sleep(ThreadSimpleImpl *thread, double seconds);
62  void enqueue_block(ThreadSimpleImpl *thread, BlockerSimple *blocker);
63  bool unblock_one(BlockerSimple *blocker);
64  bool unblock_all(BlockerSimple *blocker);
65  void enqueue_finished(ThreadSimpleImpl *thread);
66  void preempt(ThreadSimpleImpl *thread);
67  void next_context();
68 
69  void prepare_for_exit();
70 
71  INLINE ThreadSimpleImpl *get_current_thread();
72  void set_current_thread(ThreadSimpleImpl *current_thread);
73  INLINE bool is_same_system_thread() const;
74  void remove_thread(ThreadSimpleImpl *thread);
75  static void system_sleep(double seconds);
76  static void system_yield();
77 
78  double get_current_time() const;
79  INLINE static ThreadSimpleManager *get_global_ptr();
80 
81  void write_status(std::ostream &out) const;
82 
83 private:
84  static void init_pointers();
85 
86  typedef pdeque<ThreadSimpleImpl *> FifoThreads;
87  typedef pvector<ThreadSimpleImpl *> Sleeping;
88 
89  static void st_choose_next_context(struct ThreadContext *from_context, void *data);
90  void choose_next_context(struct ThreadContext *from_context);
91  void do_timeslice_accounting(ThreadSimpleImpl *thread, double now);
92  void wake_sleepers(Sleeping &sleepers, double now);
93  void wake_all_sleepers(Sleeping &sleepers);
94  void report_deadlock();
95  double determine_timeslice(ThreadSimpleImpl *chosen_thread);
96  void kill_non_joinable(FifoThreads &threads);
97  void kill_non_joinable(Sleeping &threads);
98 
99  // STL function object to sort the priority queue of sleeping threads.
100  class CompareStartTime {
101  public:
102  INLINE bool operator ()(ThreadSimpleImpl *a, ThreadSimpleImpl *b) const;
103  };
104 
105 public:
106  // Defined within the class to avoid static-init ordering problems.
107  ConfigVariableDouble _simple_thread_epoch_timeslice;
108  ConfigVariableDouble _simple_thread_volunteer_delay;
109  ConfigVariableDouble _simple_thread_yield_sleep;
110  ConfigVariableDouble _simple_thread_window;
111  ConfigVariableDouble _simple_thread_low_weight;
112  ConfigVariableDouble _simple_thread_normal_weight;
113  ConfigVariableDouble _simple_thread_high_weight;
114  ConfigVariableDouble _simple_thread_urgent_weight;
115 
116 private:
117  ThreadSimpleImpl *volatile _current_thread;
118 
119  // The list of ready threads: threads that are ready to execute right now.
120  FifoThreads _ready;
121 
122  // The list of threads that are ready, but will not be executed until next
123  // epoch (for instance, because they exceeded their timeslice budget this
124  // epoch).
125  FifoThreads _next_ready;
126 
127  // The list of threads that are blocked on some ConditionVar or Mutex.
128  typedef pmap<BlockerSimple *, FifoThreads> Blocked;
129  Blocked _blocked;
130 
131  // Priority queue (partially-ordered heap) of sleeping threads, based on
132  // wakeup time.
133  Sleeping _sleeping;
134 
135  // Priority queue (partially-ordered heap) of volunteer threads, based on
136  // wakeup time. This are threads that have voluntarily yielded a timeslice.
137  // They are treated the same as sleeping threads, unless all threads are
138  // sleeping.
139  Sleeping _volunteers;
140 
141  // Threads which have finished execution and are awaiting cleanup.
142  FifoThreads _finished;
143 
144  ThreadSimpleImpl *_waiting_for_exit;
145 
146  TrueClock *_clock;
147 
148  double _tick_scale;
149 
150  class TickRecord {
151  public:
152  unsigned int _tick_count;
153  ThreadSimpleImpl *_thread;
154  };
155  typedef pdeque<TickRecord> TickRecords;
156  TickRecords _tick_records;
157  unsigned int _total_ticks;
158 
159  static bool _pointers_initialized;
160  static ThreadSimpleManager *_global_ptr;
161 };
162 
163 // We include this down here to avoid the circularity problem.
164 /* okcircular */
165 #include "threadSimpleImpl.h"
166 
167 #include "threadSimpleManager.I"
168 
169 #endif // THREAD_SIMPLE_IMPL
170 
171 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
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 deque.
Definition: pdeque.h:36
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
This is a convenience class to specialize ConfigVariable as a floating- point type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An interface to whatever real-time clock we might have available in the current environment.
Definition: trueClock.h:33
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.