Panda3D
 All Classes Functions Variables Enumerations
pStatClient.h
1 // Filename: pStatClient.h
2 // Created by: drose (09Jul00)
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 PSTATCLIENT_H
16 #define PSTATCLIENT_H
17 
18 #include "pandabase.h"
19 
20 #include "pStatFrameData.h"
21 #include "pStatClientImpl.h"
22 #include "pStatCollectorDef.h"
23 #include "reMutex.h"
24 #include "lightMutex.h"
25 #include "reMutexHolder.h"
26 #include "lightMutexHolder.h"
27 #include "pmap.h"
28 #include "thread.h"
29 #include "weakPointerTo.h"
30 #include "vector_int.h"
31 #include "atomicAdjust.h"
32 #include "numeric_types.h"
33 #include "bitArray.h"
34 
35 class PStatCollector;
36 class PStatCollectorDef;
37 class PStatThread;
39 
40 ////////////////////////////////////////////////////////////////////
41 // Class : PStatClient
42 // Description : Manages the communications to report statistics via a
43 // network connection to a remote PStatServer.
44 //
45 // Normally, there is only one PStatClient in the world,
46 // although it is possible to have multiple PStatClients
47 // if extraordinary circumstances require in. Since
48 // each PStatCollector registers itself with the
49 // PStatClient when it is created, having multiple
50 // PStatClients requires special care when constructing
51 // the various PStatCollectors.
52 //
53 // If DO_PSTATS is not defined, we don't want to use
54 // stats at all. This class is therefore defined as a
55 // stub class.
56 ////////////////////////////////////////////////////////////////////
57 #ifdef DO_PSTATS
58 class EXPCL_PANDA_PSTATCLIENT PStatClient : public ConnectionManager, public Thread::PStatsCallback {
59 public:
60  PStatClient();
61  ~PStatClient();
62 
63 PUBLISHED:
64  INLINE void set_client_name(const string &name);
65  INLINE string get_client_name() const;
66  INLINE void set_max_rate(double rate);
67  INLINE double get_max_rate() const;
68 
69  INLINE int get_num_collectors() const;
70  PStatCollector get_collector(int index) const;
71  MAKE_SEQ(get_collectors, get_num_collectors, get_collector);
72  INLINE PStatCollectorDef *get_collector_def(int index) const;
73  string get_collector_name(int index) const;
74  string get_collector_fullname(int index) const;
75 
76  INLINE int get_num_threads() const;
77  PStatThread get_thread(int index) const;
78  MAKE_SEQ(get_threads, get_num_threads, get_thread);
79  INLINE string get_thread_name(int index) const;
80  INLINE string get_thread_sync_name(int index) const;
81  INLINE Thread *get_thread_object(int index) const;
82 
85 
86  INLINE double get_real_time() const;
87 
88  INLINE static bool connect(const string &hostname = string(), int port = -1);
89  INLINE static void disconnect();
90  INLINE static bool is_connected();
91 
92  INLINE static void resume_after_pause();
93 
94  static void main_tick();
95  static void thread_tick(const string &sync_name);
96 
97  void client_main_tick();
98  void client_thread_tick(const string &sync_name);
99  INLINE bool client_connect(string hostname, int port);
100  void client_disconnect();
101  INLINE bool client_is_connected() const;
102 
103  INLINE void client_resume_after_pause();
104 
105  static PStatClient *get_global_pstats();
106 
107 private:
108  INLINE bool has_impl() const;
109  INLINE PStatClientImpl *get_impl();
110  INLINE const PStatClientImpl *get_impl() const;
111 
112  PStatCollector make_collector_with_relname(int parent_index, string relname);
113  PStatCollector make_collector_with_name(int parent_index, const string &name);
114  PStatThread do_get_current_thread() const;
115  PStatThread make_thread(Thread *thread);
116  PStatThread do_make_thread(Thread *thread);
117  PStatThread make_gpu_thread(const string &name);
118 
119  bool is_active(int collector_index, int thread_index) const;
120  bool is_started(int collector_index, int thread_index) const;
121 
122  void start(int collector_index, int thread_index);
123  void start(int collector_index, int thread_index, double as_of);
124  void stop(int collector_index, int thread_index);
125  void stop(int collector_index, int thread_index, double as_of);
126 
127  void clear_level(int collector_index, int thread_index);
128  void set_level(int collector_index, int thread_index, double level);
129  void add_level(int collector_index, int thread_index, double increment);
130  double get_level(int collector_index, int thread_index) const;
131 
132  static void start_clock_wait();
133  static void start_clock_busy_wait();
134  static void stop_clock_wait();
135 
136  class Collector;
137  class InternalThread;
138  void add_collector(Collector *collector);
139  void add_thread(InternalThread *thread);
140 
141  INLINE Collector *get_collector_ptr(int collector_index) const;
142  INLINE InternalThread *get_thread_ptr(int thread_index) const;
143 
144  virtual void deactivate_hook(Thread *thread);
145  virtual void activate_hook(Thread *thread);
146 
147 private:
148  // This mutex protects everything in this class.
149  ReMutex _lock;
150 
151  typedef pmap<string, int> ThingsByName;
152  typedef pmap<string, vector_int> MultiThingsByName;
153  MultiThingsByName _threads_by_name, _threads_by_sync_name;
154 
155  // This is for the data that is per-collector, per-thread. A vector
156  // of these is stored in each Collector object, below, indexed by
157  // thread index.
158  class PerThreadData {
159  public:
160  PerThreadData();
161  bool _has_level;
162  double _level;
163  int _nested_count;
164  };
165  typedef pvector<PerThreadData> PerThread;
166 
167  // This is where the meat of the Collector data is stored. (All the
168  // stuff in PStatCollector and PStatCollectorDef is just fluff.)
169  class Collector {
170  public:
171  INLINE Collector(int parent_index, const string &name);
172  INLINE int get_parent_index() const;
173  INLINE const string &get_name() const;
174  INLINE bool is_active() const;
175  INLINE PStatCollectorDef *get_def(const PStatClient *client, int this_index) const;
176 
177  private:
178  void make_def(const PStatClient *client, int this_index);
179 
180  private:
181  // This pointer is initially NULL, and will be filled in when it
182  // is first needed.
183  PStatCollectorDef *_def;
184 
185  // This data is used to create the PStatCollectorDef when it is
186  // needed.
187  int _parent_index;
188  string _name;
189 
190  public:
191  // Relations to other collectors.
192  ThingsByName _children;
193  PerThread _per_thread;
194  };
195  typedef Collector *CollectorPointer;
196  AtomicAdjust::Pointer _collectors; // CollectorPointer *_collectors;
197  AtomicAdjust::Integer _collectors_size; // size of the allocated array
198  AtomicAdjust::Integer _num_collectors; // number of in-use elements within the array
199 
200  // This defines a single thread, i.e. a separate chain of execution,
201  // independent of all other threads. Timing and level data are
202  // maintained separately for each thread.
203  class InternalThread {
204  public:
205  InternalThread(Thread *thread);
206  InternalThread(const string &name, const string &sync_name = "Main");
207 
208  WPT(Thread) _thread;
209  string _name;
210  string _sync_name;
211  PStatFrameData _frame_data;
212  bool _is_active;
213  int _frame_number;
214  double _next_packet;
215 
216  bool _thread_active;
217  BitArray _active_collectors; // no longer used.
218 
219  // This mutex is used to protect writes to _frame_data for this
220  // particular thread, as well as writes to the _per_thread data
221  // for this particular thread in the Collector class, above.
222  LightMutex _thread_lock;
223  };
224  typedef InternalThread *ThreadPointer;
225  AtomicAdjust::Pointer _threads; // ThreadPointer *_threads;
226  AtomicAdjust::Integer _threads_size; // size of the allocated array
227  AtomicAdjust::Integer _num_threads; // number of in-use elements within the array
228 
229  PStatClientImpl *_impl;
230 
231  static PStatCollector _heap_total_size_pcollector;
232  static PStatCollector _heap_overhead_size_pcollector;
233  static PStatCollector _heap_single_size_pcollector;
234  static PStatCollector _heap_single_other_size_pcollector;
235  static PStatCollector _heap_array_size_pcollector;
236  static PStatCollector _heap_array_other_size_pcollector;
237  static PStatCollector _heap_external_size_pcollector;
238  static PStatCollector _mmap_size_pcollector;
239 
240  static PStatCollector _mmap_nf_unused_size_pcollector;
241  static PStatCollector _mmap_dc_active_other_size_pcollector;
242  static PStatCollector _mmap_dc_inactive_other_size_pcollector;
243  static PStatCollector _pstats_pcollector;
244  static PStatCollector _clock_wait_pcollector;
245  static PStatCollector _clock_busy_wait_pcollector;
246  static PStatCollector _thread_block_pcollector;
247 
248  static PStatClient *_global_pstats;
249 
250  friend class Collector;
251  friend class PStatCollector;
252  friend class PStatThread;
253  friend class PStatClientImpl;
254  friend class GraphicsStateGuardian;
255 };
256 
257 #include "pStatClient.I"
258 
259 #else // DO_PSTATS
260 
261 class EXPCL_PANDA_PSTATCLIENT PStatClient {
262 public:
263  PStatClient() { }
264  ~PStatClient() { }
265 
266 PUBLISHED:
267  INLINE static bool connect(const string & = string(), int = -1) { return false; }
268  INLINE static void disconnect() { }
269  INLINE static bool is_connected() { return false; }
270  INLINE static void resume_after_pause() { }
271 
272  INLINE static void main_tick() { }
273  INLINE static void thread_tick(const string &) { }
274 };
275 
276 #endif // DO_PSTATS
277 
278 #endif
static bool connect(const string &=string(), int=-1)
Attempts to establish a connection to the indicated PStatServer.
Definition: pStatClient.h:267
The primary interface to the low-level networking layer in this package.
static void resume_after_pause()
Resumes the PStatClient after the simulation has been paused for a while.
Definition: pStatClient.h:270
static void disconnect()
Closes the connection previously established.
Definition: pStatClient.h:268
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
Definition: thread.I:145
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
A dynamic array with an unlimited number of bits.
Definition: bitArray.h:42
static Thread * get_main_thread()
Returns a pointer to the &quot;main&quot; Thread object–this is the Thread that started the whole process...
Definition: thread.I:107
virtual void activate_hook(Thread *thread)
Called when the thread is activated (resumes execution).
Definition: thread.cxx:575
A lightweight class that represents a single element that may be timed and/or counted via stats...
A trivial implementation for atomic adjustments for systems that don&#39;t require multiprogramming, and therefore don&#39;t require special atomic operations.
Contains the raw timing and level data for a single frame.
bool is_started() const
Returns true if the thread has been started, false if it has not, or if join() has already been calle...
Definition: thread.I:275
A lightweight class that represents a single thread of execution to PStats.
Definition: pStatThread.h:31
A thread; that is, a lightweight process.
Definition: thread.h:51
Encapsulates all the communication with a particular instance of a given rendering backend...
static bool is_connected()
Returns true if the client believes it is connected to a working PStatServer, false otherwise...
Definition: pStatClient.h:269
Defines the details about the Collectors: the name, the suggested color, etc.
This is a standard, non-reentrant mutex, similar to the Mutex class.
Definition: lightMutex.h:45
Manages the communications to report statistics via a network connection to a remote PStatServer...
Definition: pStatClient.h:261
virtual void deactivate_hook(Thread *thread)
Called when the thread is deactivated (swapped for another running thread).
Definition: thread.cxx:563
A reentrant mutex.
Definition: reMutex.h:36
bool start(ThreadPriority priority, bool joinable)
Starts the thread executing.
Definition: thread.cxx:242