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