Panda3D
dtoolbase_cc.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 dtoolbase_cc.h
10  * @author drose
11  * @date 2000-09-13
12  */
13 
14 #ifndef DTOOLBASE_CC_H
15 #define DTOOLBASE_CC_H
16 
17 // This file should never be included directly; it's intended to be included
18 // only from dtoolbase.h. Include that file instead.
19 
20 #ifdef __cplusplus
21 
22 // By including checkPandaVersion.h, we guarantee that runtime attempts to
23 // load any DLL will fail if they inadvertently link with the wrong version of
24 // dtool, which, transitively, means all DLLs must be from the same
25 // (ABI-compatible) version of Panda.
26 
27 #include "checkPandaVersion.h"
28 
29 #ifdef USE_TAU
30 // Tau provides this destructive version of stdbool.h that we must mask.
31 #define __PDT_STDBOOL_H_
32 #endif
33 
34 #ifdef CPPPARSER
35 #include <iostream>
36 #include <iomanip>
37 #include <string>
38 #include <utility>
39 #include <algorithm>
40 
41 #define INLINE inline
42 #define ALWAYS_INLINE inline
43 #define MOVE(x) x
44 
45 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
46 
47 // We define the macro PUBLISHED to mark C++ methods that are to be published
48 // via interrogate to scripting languages. However, if we're not running the
49 // interrogate pass (CPPPARSER isn't defined), this maps to public.
50 #define PUBLISHED __published
51 
52 #define PHAVE_ATOMIC 1
53 
54 typedef int ios_openmode;
55 typedef int ios_fmtflags;
56 typedef int ios_iostate;
57 typedef int ios_seekdir;
58 
59 #else // CPPPARSER
60 
61 #ifdef PHAVE_IOSTREAM
62 #include <iostream>
63 #include <fstream>
64 #include <iomanip>
65 #else
66 #include <iostream.h>
67 #include <fstream.h>
68 #include <iomanip.h>
69 #endif
70 
71 #ifdef PHAVE_SSTREAM
72 #include <sstream>
73 #else
74 #include "fakestringstream.h"
75 #endif
76 
77 #ifdef PHAVE_NEW
78 #include <new>
79 #endif
80 
81 #include <string>
82 #include <utility>
83 #include <algorithm>
84 
85 #ifndef HAVE_IOS_TYPEDEFS
86 typedef int ios_openmode;
87 typedef int ios_fmtflags;
88 typedef int ios_iostate;
89 // Old iostream libraries used ios::seek_dir instead of ios::seekdir.
90 typedef ios::seek_dir ios_seekdir;
91 #else
92 typedef std::ios::openmode ios_openmode;
93 typedef std::ios::fmtflags ios_fmtflags;
94 typedef std::ios::iostate ios_iostate;
95 typedef std::ios::seekdir ios_seekdir;
96 #endif
97 
98 #ifdef _MSC_VER
99 #define ALWAYS_INLINE __forceinline
100 #elif defined(__GNUC__)
101 #define ALWAYS_INLINE __attribute__((always_inline)) inline
102 #else
103 #define ALWAYS_INLINE inline
104 #endif
105 
106 #ifdef FORCE_INLINING
107 // If FORCE_INLINING is defined, we use the keyword __forceinline, which tells
108 // MS VC++ to override its internal benefit heuristic and inline the fn if it
109 // is technically possible to do so.
110 #define INLINE ALWAYS_INLINE
111 #else
112 #define INLINE inline
113 #endif
114 
115 // Apple has an outdated libstdc++. Not all is lost, though, as we can fill
116 // in some important missing functions.
117 #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719
118 #include <tr1/tuple>
119 #include <tr1/cmath>
120 
121 namespace std {
122  using std::tr1::tuple;
123  using std::tr1::tie;
124  using std::tr1::copysign;
125 
126  typedef decltype(nullptr) nullptr_t;
127 
128  template<class T> struct remove_reference {typedef T type;};
129  template<class T> struct remove_reference<T&> {typedef T type;};
130  template<class T> struct remove_reference<T&& >{typedef T type;};
131 
132  template<class T> typename remove_reference<T>::type &&move(T &&t) {
133  return static_cast<typename remove_reference<T>::type&&>(t);
134  }
135 
136  template<class T> struct owner_less;
137 
138  typedef enum memory_order {
139  memory_order_relaxed,
140  memory_order_consume,
141  memory_order_acquire,
142  memory_order_release,
143  memory_order_acq_rel,
144  memory_order_seq_cst,
145  } memory_order;
146 
147  #define ATOMIC_FLAG_INIT { 0 }
148  class atomic_flag {
149  bool _flag;
150 
151  public:
152  atomic_flag() noexcept = default;
153  ALWAYS_INLINE constexpr atomic_flag(bool flag) noexcept : _flag(flag) {}
154  atomic_flag(const atomic_flag &) = delete;
155  ~atomic_flag() noexcept = default;
156  atomic_flag &operator = (const atomic_flag&) = delete;
157 
158  ALWAYS_INLINE bool test_and_set(memory_order order = memory_order_seq_cst) noexcept {
159  return __atomic_test_and_set(&_flag, order);
160  }
161  ALWAYS_INLINE void clear(memory_order order = memory_order_seq_cst) noexcept {
162  __atomic_clear(&_flag, order);
163  }
164  };
165 };
166 #else
167 // Expect that we have access to the <atomic> header.
168 #define PHAVE_ATOMIC 1
169 #endif
170 
171 // Determine the availability of C++11 features.
172 #if defined(_MSC_VER) && _MSC_VER < 1900 // Visual Studio 2015
173 #error Microsoft Visual C++ 2015 or later is required to compile Panda3D.
174 #endif
175 
176 // This is just to support code generated with older versions of interrogate.
177 #define MOVE(x) (std::move(x))
178 
179 
180 #ifndef LINK_ALL_STATIC
181 // This macro must be used to export an instantiated template class from a
182 // DLL. If the template class name itself contains commas, it may be
183 // necessary to first define a macro for the class name, to allow proper macro
184 // parameter passing.
185 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname) \
186  exptp template class expcl classname;
187 #else
188 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
189 #endif
190 
191 // We define the macro PUBLISHED to mark C++ methods that are to be published
192 // via interrogate to scripting languages. However, if we're not running the
193 // interrogate pass (CPPPARSER isn't defined), this maps to public.
194 #define PUBLISHED public
195 
196 #endif // CPPPARSER
197 
198 // The ReferenceCount class is defined later, within Panda, but we need to
199 // pass around forward references to it here at the very low level.
200 class ReferenceCount;
201 
202 // We need a pointer to a global MemoryHook object, to manage all malloc and
203 // free requests from Panda. See the comments in MemoryHook itself.
204 class MemoryHook;
205 EXPCL_DTOOL_DTOOLBASE extern MemoryHook *memory_hook;
206 EXPCL_DTOOL_DTOOLBASE void init_memory_hook();
207 
208 // Now redefine some handy macros to hook into the above MemoryHook object.
209 #ifndef USE_MEMORY_NOWRAPPERS
210 #define PANDA_MALLOC_SINGLE(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_single(size), MEMORY_HOOK_ALIGNMENT))
211 #define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
212 #define PANDA_MALLOC_ARRAY(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_array(size), MEMORY_HOOK_ALIGNMENT))
213 #define PANDA_REALLOC_ARRAY(ptr, size) (ASSUME_ALIGNED(memory_hook->heap_realloc_array(ptr, size), MEMORY_HOOK_ALIGNMENT))
214 #define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
215 #else
216 #define PANDA_MALLOC_SINGLE(size) ::malloc(size)
217 #define PANDA_FREE_SINGLE(ptr) ::free(ptr)
218 #define PANDA_MALLOC_ARRAY(size) ::malloc(size)
219 #define PANDA_REALLOC_ARRAY(ptr, size) ::realloc(ptr, size)
220 #define PANDA_FREE_ARRAY(ptr) ::free(ptr)
221 #endif // USE_MEMORY_NOWRAPPERS
222 
223 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
224 // We need another forward-reference function to allow low-level code to
225 // cooperatively yield the timeslice, in SIMPLE_THREADS mode.
226 extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_yield)();
227 extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_consider_yield)();
228 
229 INLINE void thread_yield() {
230  (*global_thread_yield)();
231 }
232 INLINE void thread_consider_yield() {
233  (*global_thread_consider_yield)();
234 }
235 
236 #ifdef HAVE_PYTHON
237 typedef struct _ts PyThreadState;
238 extern EXPCL_DTOOL_DTOOLBASE PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate);
239 
240 INLINE PyThreadState *thread_state_swap(PyThreadState *tstate) {
241  return (*global_thread_state_swap)(tstate);
242 }
243 #endif // HAVE_PYTHON
244 
245 #else
246 
247 INLINE void thread_yield() {
248 }
249 INLINE void thread_consider_yield() {
250 }
251 
252 #endif // HAVE_THREADS && SIMPLE_THREADS
253 
254 #if defined(USE_TAU) && defined(WIN32)
255 // Hack around tau's lack of DLL export declarations for Profiler class.
256 extern EXPCL_DTOOL_DTOOLBASE bool __tau_shutdown;
257 class EXPCL_DTOOL_DTOOLBASE TauProfile {
258 public:
259  TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
260  Tau_profile_c_timer(&tautimer, name, type, group, group_name);
261  _tautimer = tautimer;
262  TAU_PROFILE_START(_tautimer);
263  }
264  ~TauProfile() {
265  if (!__tau_shutdown) {
266  TAU_PROFILE_STOP(_tautimer);
267  }
268  }
269 
270 private:
271  void *_tautimer;
272 };
273 
274 #undef TAU_PROFILE
275 #define TAU_PROFILE(name, type, group) \
276  static void *__tautimer; \
277  TauProfile __taupr(__tautimer, name, type, group, #group)
278 
279 #undef TAU_PROFILE_EXIT
280 #define TAU_PROFILE_EXIT(msg) \
281  __tau_shutdown = true; \
282  Tau_exit(msg);
283 
284 #endif // USE_TAU
285 
286 #endif // __cplusplus
287 #endif
void init_memory_hook()
Any code that might need to use PANDA_MALLOC or PANDA_FREE, or any methods of the global memory_hook ...
Definition: dtoolbase.cxx:38
A base class for all things that want to be reference-counted.
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition: memoryHook.h:37