Panda3D
 All Classes Functions Variables Enumerations
asyncTaskChain.h
1 // Filename: asyncTaskChain.h
2 // Created by: drose (23Aug06)
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 #ifndef ASYNCTASKCHAIN_H
16 #define ASYNCTASKCHAIN_H
17 
18 #include "pandabase.h"
19 
20 #include "asyncTask.h"
21 #include "asyncTaskCollection.h"
22 #include "typedReferenceCount.h"
23 #include "thread.h"
24 #include "conditionVarFull.h"
25 #include "pvector.h"
26 #include "pdeque.h"
27 #include "pStatCollector.h"
28 #include "clockObject.h"
29 
30 class AsyncTaskManager;
31 
32 ////////////////////////////////////////////////////////////////////
33 // Class : AsyncTaskChain
34 // Description : The AsyncTaskChain is a subset of the
35 // AsyncTaskManager. Each chain maintains a separate
36 // list of tasks, and will execute them with its own set
37 // of threads. Each chain may thereby operate
38 // independently of the other chains.
39 //
40 // The AsyncTaskChain will spawn a specified number of
41 // threads (possibly 0) to serve the tasks. If there
42 // are no threads, you must call poll() from time to
43 // time to serve the tasks in the main thread. Normally
44 // this is done by calling AsyncTaskManager::poll().
45 //
46 // Each task will run exactly once each epoch. Beyond
47 // that, the tasks' sort and priority values control the
48 // order in which they are run: tasks are run in
49 // increasing order by sort value, and within the same
50 // sort value, they are run roughly in decreasing order
51 // by priority value, with some exceptions for
52 // parallelism. Tasks with different sort values are
53 // never run in parallel together, but tasks with
54 // different priority values might be (if there is more
55 // than one thread).
56 ////////////////////////////////////////////////////////////////////
57 class EXPCL_PANDA_EVENT AsyncTaskChain : public TypedReferenceCount, public Namable {
58 public:
59  AsyncTaskChain(AsyncTaskManager *manager, const string &name);
60  ~AsyncTaskChain();
61 
62 PUBLISHED:
63  void set_tick_clock(bool tick_clock);
64  bool get_tick_clock() const;
65 
66  BLOCKING void set_num_threads(int num_threads);
67  int get_num_threads() const;
68  int get_num_running_threads() const;
69 
70  BLOCKING void set_thread_priority(ThreadPriority priority);
71  ThreadPriority get_thread_priority() const;
72 
73  void set_frame_budget(double frame_budget);
74  double get_frame_budget() const;
75 
76  void set_frame_sync(bool frame_sync);
77  bool get_frame_sync() const;
78 
79  void set_timeslice_priority(bool timeslice_priority);
80  bool get_timeslice_priority() const;
81 
82  BLOCKING void stop_threads();
83  void start_threads();
84  INLINE bool is_started() const;
85 
86  bool has_task(AsyncTask *task) const;
87 
88  BLOCKING void wait_for_tasks();
89 
90  int get_num_tasks() const;
91  AsyncTaskCollection get_tasks() const;
92  AsyncTaskCollection get_active_tasks() const;
93  AsyncTaskCollection get_sleeping_tasks() const;
94 
95  void poll();
96  double get_next_wake_time() const;
97 
98  virtual void output(ostream &out) const;
99  virtual void write(ostream &out, int indent_level = 0) const;
100 
101 protected:
102  class AsyncTaskChainThread;
104 
105  void do_add(AsyncTask *task);
106  bool do_remove(AsyncTask *task);
107  void do_wait_for_tasks();
108  void do_cleanup();
109 
110  bool do_has_task(AsyncTask *task) const;
111  int find_task_on_heap(const TaskHeap &heap, AsyncTask *task) const;
112 
113  void service_one_task(AsyncTaskChainThread *thread);
114  void cleanup_task(AsyncTask *task, bool upon_death, bool clean_exit);
115  bool finish_sort_group();
116  void filter_timeslice_priority();
117  void do_stop_threads();
118  void do_start_threads();
119  AsyncTaskCollection do_get_active_tasks() const;
120  AsyncTaskCollection do_get_sleeping_tasks() const;
121  void do_poll();
122  void cleanup_pickup_mode();
123  INLINE double do_get_next_wake_time() const;
124  static INLINE double get_wake_time(AsyncTask *task);
125  void do_output(ostream &out) const;
126  void do_write(ostream &out, int indent_level) const;
127 
128  void write_task_line(ostream &out, int indent_level, AsyncTask *task, double now) const;
129 
130 protected:
131  class AsyncTaskChainThread : public Thread {
132  public:
133  AsyncTaskChainThread(const string &name, AsyncTaskChain *chain);
134  virtual void thread_main();
135 
136  AsyncTaskChain *_chain;
137  AsyncTask *_servicing;
138  };
139 
140  class AsyncTaskSortWakeTime {
141  public:
142  bool operator () (AsyncTask *a, AsyncTask *b) const {
143  return AsyncTaskChain::get_wake_time(a) > AsyncTaskChain::get_wake_time(b);
144  }
145  };
146 
147  class AsyncTaskSortPriority {
148  public:
149  bool operator () (AsyncTask *a, AsyncTask *b) const {
150  if (a->get_sort() != b->get_sort()) {
151  return a->get_sort() > b->get_sort();
152  }
153  if (a->get_priority() != b->get_priority()) {
154  return a->get_priority() < b->get_priority();
155  }
156  return a->get_start_time() > b->get_start_time();
157  }
158  };
159 
161 
162  AsyncTaskManager *_manager;
163 
164  ConditionVarFull _cvar; // signaled when one of the task heaps, _state, or _current_sort changes, or a task finishes.
165 
166  enum State {
167  S_initial, // no threads yet
168  S_started, // threads have been started
169  S_interrupted, // task returned DS_interrupt, requested from sub-thread.
170  S_shutdown // waiting for thread shutdown, requested from main thread
171  };
172 
173  bool _tick_clock;
174  bool _timeslice_priority;
175  int _num_threads;
176  ThreadPriority _thread_priority;
177  Threads _threads;
178  double _frame_budget;
179  bool _frame_sync;
180  int _num_busy_threads;
181  int _num_tasks;
182  TaskHeap _active;
183  TaskHeap _this_active;
184  TaskHeap _next_active;
185  TaskHeap _sleeping;
186  State _state;
187  int _current_sort;
188  bool _pickup_mode;
189  bool _needs_cleanup;
190 
191  int _current_frame;
192  double _time_in_frame;
193  bool _block_till_next_frame;
194 
195  static PStatCollector _task_pcollector;
196  static PStatCollector _wait_pcollector;
197 
198 public:
199  static TypeHandle get_class_type() {
200  return _type_handle;
201  }
202  static void init_type() {
203  TypedReferenceCount::init_type();
204  register_type(_type_handle, "AsyncTaskChain",
205  TypedReferenceCount::get_class_type());
206  }
207  virtual TypeHandle get_type() const {
208  return get_class_type();
209  }
210  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
211 
212 private:
213  static TypeHandle _type_handle;
214 
215  friend class AsyncTaskChainThread;
216  friend class AsyncTask;
217  friend class AsyncTaskManager;
218  friend class AsyncTaskSortWakeTime;
219 };
220 
221 INLINE ostream &operator << (ostream &out, const AsyncTaskChain &chain) {
222  chain.output(out);
223  return out;
224 };
225 
226 #include "asyncTaskChain.I"
227 
228 #endif
int get_priority() const
Returns the task&#39;s current priority value.
Definition: asyncTask.I:209
double get_start_time() const
Returns the time at which the task was started, according to the task manager&#39;s clock.
Definition: asyncTask.I:137
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
A list of tasks, for instance as returned by some of the AsyncTaskManager query functions.
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
int get_sort() const
Returns the task&#39;s current sort value.
Definition: asyncTask.I:198
A lightweight class that represents a single element that may be timed and/or counted via stats...
A base class for all things which can have a name.
Definition: namable.h:29
The AsyncTaskChain is a subset of the AsyncTaskManager.
This class represents a concrete task performed by an AsyncManager.
Definition: asyncTask.h:43
void output(ostream &out) const
Outputs the Namable.
Definition: namable.I:97
This class implements a condition variable; see ConditionVar for a brief introduction to this class...
A thread; that is, a lightweight process.
Definition: thread.h:51
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85