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
MemoryHook
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition: memoryHook.h:37
ReferenceCount
A base class for all things that want to be reference-counted.
Definition: referenceCount.h:38
init_memory_hook
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