Panda3D
Loading...
Searching...
No Matches
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
54typedef int ios_openmode;
55typedef int ios_fmtflags;
56typedef int ios_iostate;
57typedef 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
86typedef int ios_openmode;
87typedef int ios_fmtflags;
88typedef int ios_iostate;
89// Old iostream libraries used ios::seek_dir instead of ios::seekdir.
90typedef ios::seek_dir ios_seekdir;
91#else
92typedef std::ios::openmode ios_openmode;
93typedef std::ios::fmtflags ios_fmtflags;
94typedef std::ios::iostate ios_iostate;
95typedef 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
121namespace 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 ALWAYS_INLINE float round(float arg) {
167 return ::roundf(arg);
168 }
169 ALWAYS_INLINE double round(double arg) {
170 return ::round(arg);
171 }
172 ALWAYS_INLINE long double round(long double arg) {
173 return ::roundl(arg);
174 }
175 ALWAYS_INLINE double round(signed char arg) {
176 return (double)arg;
177 }
178 ALWAYS_INLINE double round(unsigned char arg) {
179 return (double)arg;
180 }
181 ALWAYS_INLINE double round(short arg) {
182 return (double)arg;
183 }
184 ALWAYS_INLINE double round(unsigned short arg) {
185 return (double)arg;
186 }
187 ALWAYS_INLINE double round(int arg) {
188 return (double)arg;
189 }
190 ALWAYS_INLINE double round(unsigned int arg) {
191 return (double)arg;
192 }
193 ALWAYS_INLINE double round(long arg) {
194 return (double)arg;
195 }
196 ALWAYS_INLINE double round(unsigned long arg) {
197 return (double)arg;
198 }
199 ALWAYS_INLINE double round(long long arg) {
200 return (double)arg;
201 }
202 ALWAYS_INLINE double round(unsigned long long arg) {
203 return (double)arg;
204 }
205 using ::roundf;
206 using ::roundl;
207};
208#else
209// Expect that we have access to the <atomic> header.
210#define PHAVE_ATOMIC 1
211#endif
212
213// Determine the availability of C++11 features.
214#if defined(_MSC_VER) && _MSC_VER < 1900 // Visual Studio 2015
215#error Microsoft Visual C++ 2015 or later is required to compile Panda3D.
216#endif
217
218// This is just to support code generated with older versions of interrogate.
219#define MOVE(x) (std::move(x))
220
221
222#ifndef LINK_ALL_STATIC
223// This macro must be used to export an instantiated template class from a
224// DLL. If the template class name itself contains commas, it may be
225// necessary to first define a macro for the class name, to allow proper macro
226// parameter passing.
227#define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname) \
228 exptp template class expcl classname;
229#else
230#define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
231#endif
232
233// We define the macro PUBLISHED to mark C++ methods that are to be published
234// via interrogate to scripting languages. However, if we're not running the
235// interrogate pass (CPPPARSER isn't defined), this maps to public.
236#define PUBLISHED public
237
238#endif // CPPPARSER
239
240// The ReferenceCount class is defined later, within Panda, but we need to
241// pass around forward references to it here at the very low level.
242class ReferenceCount;
243
244// We need a pointer to a global MemoryHook object, to manage all malloc and
245// free requests from Panda. See the comments in MemoryHook itself.
246class MemoryHook;
247EXPCL_DTOOL_DTOOLBASE extern MemoryHook *memory_hook;
248EXPCL_DTOOL_DTOOLBASE void init_memory_hook();
249
250// Now redefine some handy macros to hook into the above MemoryHook object.
251#ifndef USE_MEMORY_NOWRAPPERS
252#define PANDA_MALLOC_SINGLE(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_single(size), MEMORY_HOOK_ALIGNMENT))
253#define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
254#define PANDA_MALLOC_ARRAY(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_array(size), MEMORY_HOOK_ALIGNMENT))
255#define PANDA_REALLOC_ARRAY(ptr, size) (ASSUME_ALIGNED(memory_hook->heap_realloc_array(ptr, size), MEMORY_HOOK_ALIGNMENT))
256#define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
257#else
258#define PANDA_MALLOC_SINGLE(size) ::malloc(size)
259#define PANDA_FREE_SINGLE(ptr) ::free(ptr)
260#define PANDA_MALLOC_ARRAY(size) ::malloc(size)
261#define PANDA_REALLOC_ARRAY(ptr, size) ::realloc(ptr, size)
262#define PANDA_FREE_ARRAY(ptr) ::free(ptr)
263#endif // USE_MEMORY_NOWRAPPERS
264
265#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
266// We need another forward-reference function to allow low-level code to
267// cooperatively yield the timeslice, in SIMPLE_THREADS mode.
268extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_yield)();
269extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_consider_yield)();
270
271INLINE void thread_yield() {
272 (*global_thread_yield)();
273}
274INLINE void thread_consider_yield() {
275 (*global_thread_consider_yield)();
276}
277
278#ifdef HAVE_PYTHON
279typedef struct _ts PyThreadState;
280extern EXPCL_DTOOL_DTOOLBASE PyThreadState *(*global_thread_state_swap)(PyThreadState *tstate);
281
282INLINE PyThreadState *thread_state_swap(PyThreadState *tstate) {
283 return (*global_thread_state_swap)(tstate);
284}
285#endif // HAVE_PYTHON
286
287#else
288
289INLINE void thread_yield() {
290}
291INLINE void thread_consider_yield() {
292}
293
294#endif // HAVE_THREADS && SIMPLE_THREADS
295
296#if defined(USE_TAU) && defined(WIN32)
297// Hack around tau's lack of DLL export declarations for Profiler class.
298extern EXPCL_DTOOL_DTOOLBASE bool __tau_shutdown;
299class EXPCL_DTOOL_DTOOLBASE TauProfile {
300public:
301 TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
302 Tau_profile_c_timer(&tautimer, name, type, group, group_name);
303 _tautimer = tautimer;
304 TAU_PROFILE_START(_tautimer);
305 }
306 ~TauProfile() {
307 if (!__tau_shutdown) {
308 TAU_PROFILE_STOP(_tautimer);
309 }
310 }
311
312private:
313 void *_tautimer;
314};
315
316#undef TAU_PROFILE
317#define TAU_PROFILE(name, type, group) \
318 static void *__tautimer; \
319 TauProfile __taupr(__tautimer, name, type, group, #group)
320
321#undef TAU_PROFILE_EXIT
322#define TAU_PROFILE_EXIT(msg) \
323 __tau_shutdown = true; \
324 Tau_exit(msg);
325
326#endif // USE_TAU
327
328#endif // __cplusplus
329#endif
This class provides a wrapper around the various possible malloc schemes Panda might employ.
Definition memoryHook.h:37
A base class for all things that want to be reference-counted.
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
STL namespace.