dtoolbase.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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.h
  10. * @author drose
  11. * @date 2000-09-12
  12. */
  13. /* This file is included at the beginning of every header file and/or
  14. C or C++ file. It must be compilable for C as well as C++ files,
  15. so no C++-specific code or syntax can be put here. See
  16. dtoolbase_cc.h for C++-specific stuff. */
  17. #ifndef DTOOLBASE_H
  18. #define DTOOLBASE_H
  19. #include "dtool_config.h"
  20. /* Make sure WIN32 and WIN32_VC are defined when using MSVC */
  21. #if defined(_WIN32) || defined(_WIN64)
  22. #ifndef WIN32
  23. #define WIN32
  24. #endif
  25. #ifdef _MSC_VER
  26. #ifndef WIN32_VC
  27. #define WIN32_VC
  28. #endif
  29. #endif
  30. #endif
  31. #ifdef WIN32_VC
  32. /* These warning pragmas must appear before anything else for VC++ to
  33. respect them. Sheesh. */
  34. /* C4231: extern before template instantiation */
  35. /* For some reason, this particular warning won't disable. */
  36. #pragma warning (disable : 4231)
  37. /* C4786: 255 char debug symbols */
  38. #pragma warning (disable : 4786)
  39. /* C4251: needs dll interface */
  40. #pragma warning (disable : 4251)
  41. /* C4503: decorated name length exceeded */
  42. #pragma warning (disable : 4503)
  43. /* C4305: truncation from 'const double' to 'float' */
  44. #pragma warning (disable : 4305)
  45. /* C4250: 'myclass' : inherits 'baseclass::member' via dominance */
  46. #pragma warning (disable : 4250)
  47. /* C4355: 'this' : used in base member initializer list */
  48. #pragma warning (disable : 4355)
  49. /* C4244: 'initializing' : conversion from 'double' to 'float', possible loss of data */
  50. #pragma warning (disable : 4244)
  51. /* C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data */
  52. #pragma warning (disable : 4267)
  53. /* C4577: 'noexcept' used with no exception handling mode specified */
  54. #pragma warning (disable : 4577)
  55. #if _MSC_VER >= 1300
  56. #if _MSC_VER >= 1310
  57. #define USING_MSVC7_1
  58. // #pragma message("VC 7.1")
  59. #else
  60. // #pragma message("VC 7.0")
  61. #endif
  62. #define USING_MSVC7
  63. #else
  64. // #pragma message("VC 6.0")
  65. #endif
  66. // Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
  67. // to the final untested case after it has failed all the other cases (i.e.
  68. // 'assume at least one of the cases is always true')
  69. #ifdef _DEBUG
  70. # define NODEFAULT default: assert(0);
  71. #else
  72. # define NODEFAULT default: __assume(0); // special VC keyword
  73. #endif
  74. #else /* if !WIN32_VC */
  75. #ifdef _DEBUG
  76. # define NODEFAULT default: assert(0);
  77. #else
  78. # define NODEFAULT
  79. #endif
  80. #endif /* WIN32_VC */
  81. /*
  82. include win32 defns for everything up to WinServer2003, and assume
  83. I'm smart enough to use GetProcAddress for backward compat on
  84. w95/w98 for newer fns
  85. */
  86. #ifdef _WIN32_WINNT
  87. #undef _WIN32_WINNT
  88. #endif
  89. #define _WIN32_WINNT 0x0502
  90. #ifdef __cplusplus
  91. #ifndef __STDC_LIMIT_MACROS
  92. #define __STDC_LIMIT_MACROS
  93. #endif
  94. #ifndef __STDC_CONSTANT_MACROS
  95. #define __STDC_CONSTANT_MACROS
  96. #endif
  97. #endif
  98. // This is a workaround for a glibc bug that is triggered by clang when
  99. // compiling with -ffast-math.
  100. #ifdef __clang__
  101. #include <sys/cdefs.h>
  102. #ifndef __extern_always_inline
  103. #define __extern_always_inline extern __always_inline
  104. #endif
  105. #endif
  106. #ifdef HAVE_PYTHON
  107. // Instead of including the Python headers, which will implicitly add a linker
  108. // flag to link in Python, we'll just excerpt the forward declaration of
  109. // PyObject.
  110. typedef struct _object PyObject;
  111. #endif
  112. #ifndef HAVE_EIGEN
  113. // If we don't have the Eigen library, don't define LINMATH_ALIGN.
  114. #undef LINMATH_ALIGN
  115. #endif
  116. #include "dtoolsymbols.h"
  117. // always include assert.h until drose unbreaks it for opt4
  118. #include <assert.h>
  119. #ifdef __GNUC__
  120. // Large file >2GB support this needs be be before systypes.h and other C
  121. // headers
  122. #define _FILE_OFFSET_BITS 64
  123. #define _LARGEFILE_SOURCE 1
  124. #endif
  125. #ifdef PHAVE_TYPES_H
  126. #include <types.h>
  127. #endif
  128. #ifdef PHAVE_SYS_TYPES_H
  129. #include <sys/types.h>
  130. #endif
  131. #ifdef PHAVE_MALLOC_H
  132. #include <malloc.h>
  133. #endif
  134. #ifdef PHAVE_SYS_MALLOC_H
  135. #include <sys/malloc.h>
  136. #endif
  137. #ifdef PHAVE_ALLOCA_H
  138. #include <alloca.h>
  139. #endif
  140. #ifdef PHAVE_UNISTD_H
  141. #include <unistd.h>
  142. #endif
  143. #ifdef PHAVE_IO_H
  144. #include <io.h>
  145. #endif
  146. #ifdef PHAVE_LOCALE_H
  147. #include <locale.h>
  148. #endif
  149. #ifdef PHAVE_STRING_H
  150. #include <string.h>
  151. #endif
  152. #ifdef PHAVE_STDLIB_H
  153. #include <stdlib.h>
  154. #endif
  155. #ifdef PHAVE_LIMITS_H
  156. #include <limits.h>
  157. #endif
  158. #ifdef PHAVE_MINMAX_H
  159. #include <minmax.h>
  160. #endif
  161. #ifdef PHAVE_SYS_TIME_H
  162. #include <sys/time.h>
  163. #endif
  164. #ifdef PHAVE_STDINT_H
  165. #include <stdint.h>
  166. #endif
  167. #ifdef CPPPARSER
  168. #include <stdtypedefs.h>
  169. // Also pick up the forward declaration of PyObject.
  170. #include <Python.h>
  171. #endif
  172. #ifdef USE_TAU
  173. /* If we're building with the Tau instrumentor, include the
  174. appropriate header file to pick up the TAU macros. */
  175. #include <TAU.h>
  176. #include <Profile/Profiler.h>
  177. #else
  178. /* Otherwise, if we're not building with the Tau instrumentor, turn
  179. off all the TAU macros. We could include the Tau header file to do
  180. this, but it's better not to assume that Tau is installed. */
  181. #define TAU_TYPE_STRING(profileString, str)
  182. #define TAU_PROFILE(name, type, group)
  183. #define TAU_PROFILE_TIMER(var, name, type, group)
  184. #define TAU_PROFILE_START(var)
  185. #define TAU_PROFILE_STOP(var)
  186. #define TAU_PROFILE_STMT(stmt)
  187. #define TAU_PROFILE_EXIT(msg)
  188. #define TAU_PROFILE_INIT(argc, argv)
  189. #define TAU_PROFILE_SET_NODE(node)
  190. #define TAU_PROFILE_SET_CONTEXT(context)
  191. #define TAU_PROFILE_SET_GROUP_NAME(newname)
  192. #define TAU_PROFILE_TIMER_SET_GROUP_NAME(t, newname)
  193. #define TAU_PROFILE_CALLSTACK()
  194. #define TAU_DB_DUMP()
  195. #define TAU_DB_PURGE()
  196. #define TAU_REGISTER_CONTEXT_EVENT(event, name)
  197. #define TAU_CONTEXT_EVENT(event, data)
  198. #define TAU_DISABLE_CONTEXT_EVENT(event)
  199. #define TAU_ENABLE_CONTEXT_EVENT(event)
  200. #define TAU_REGISTER_EVENT(event, name)
  201. #define TAU_EVENT(event, data)
  202. #define TAU_EVENT_DISABLE_MIN(event)
  203. #define TAU_EVENT_DISABLE_MAX(event)
  204. #define TAU_EVENT_DISABLE_MEAN(event)
  205. #define TAU_EVENT_DISABLE_STDDEV(event)
  206. #define TAU_REPORT_STATISTICS()
  207. #define TAU_REPORT_THREAD_STATISTICS()
  208. #define TAU_REGISTER_THREAD()
  209. #define TAU_REGISTER_FORK(id, op)
  210. #define TAU_ENABLE_INSTRUMENTATION()
  211. #define TAU_DISABLE_INSTRUMENTATION()
  212. #define TAU_ENABLE_GROUP(group)
  213. #define TAU_DISABLE_GROUP(group)
  214. #define TAU_ENABLE_GROUP_NAME(group)
  215. #define TAU_DISABLE_GROUP_NAME(group)
  216. #define TAU_ENABLE_ALL_GROUPS()
  217. #define TAU_DISABLE_ALL_GROUPS()
  218. #define TAU_TRACK_MEMORY()
  219. #define TAU_TRACK_MEMORY_HERE()
  220. #define TAU_ENABLE_TRACKING_MEMORY()
  221. #define TAU_DISABLE_TRACKING_MEMORY()
  222. #define TAU_ENABLE_TRACKING_MUSE_EVENTS()
  223. #define TAU_DISABLE_TRACKING_MUSE_EVENTS()
  224. #define TAU_TRACK_MUSE_EVENTS()
  225. #define TAU_SET_INTERRUPT_INTERVAL(value)
  226. #define TAU_TRACE_SENDMSG(type, destination, length)
  227. #define TAU_TRACE_RECVMSG(type, source, length)
  228. #define TAU_MAPPING(stmt, group) stmt
  229. #define TAU_MAPPING_OBJECT(FuncInfoVar)
  230. #define TAU_MAPPING_LINK(FuncInfoVar, Group)
  231. #define TAU_MAPPING_PROFILE(FuncInfoVar)
  232. #define TAU_MAPPING_CREATE(name, type, key, groupname, tid)
  233. #define TAU_MAPPING_PROFILE_TIMER(Timer, FuncInfoVar, tid)
  234. #define TAU_MAPPING_TIMER_CREATE(t, name, type, gr, group_name)
  235. #define TAU_MAPPING_PROFILE_START(Timer, tid)
  236. #define TAU_MAPPING_PROFILE_STOP(tid)
  237. #define TAU_MAPPING_PROFILE_EXIT(msg, tid)
  238. #define TAU_MAPPING_DB_DUMP(tid)
  239. #define TAU_MAPPING_DB_PURGE(tid)
  240. #define TAU_MAPPING_PROFILE_SET_NODE(node, tid)
  241. #define TAU_MAPPING_PROFILE_SET_GROUP_NAME(timer, name)
  242. #define TAU_PROFILE_TIMER_SET_NAME(t, newname)
  243. #define TAU_PROFILE_TIMER_SET_TYPE(t, newname)
  244. #define TAU_PROFILE_TIMER_SET_GROUP(t, id)
  245. #define TAU_MAPPING_PROFILE_SET_NAME(timer, name)
  246. #define TAU_MAPPING_PROFILE_SET_TYPE(timer, name)
  247. #define TAU_MAPPING_PROFILE_SET_GROUP(timer, id)
  248. #define TAU_MAPPING_PROFILE_GET_GROUP_NAME(timer)
  249. #define TAU_MAPPING_PROFILE_GET_GROUP(timer)
  250. #define TAU_MAPPING_PROFILE_GET_NAME(timer)
  251. #define TAU_MAPPING_PROFILE_GET_TYPE(timer)
  252. #define TAU_PHASE(name, type, group)
  253. #define TAU_PHASE_CREATE_STATIC(var, name, type, group)
  254. #define TAU_PHASE_CREATE_DYNAMIC(var, name, type, group)
  255. #define TAU_PHASE_START(var)
  256. #define TAU_PHASE_STOP(var)
  257. #define TAU_GLOBAL_PHASE(timer, name, type, group)
  258. #define TAU_GLOBAL_PHASE_START(timer)
  259. #define TAU_GLOBAL_PHASE_STOP(timer)
  260. #define TAU_GLOBAL_PHASE_EXTERNAL(timer)
  261. #define TAU_GLOBAL_TIMER(timer, name, type, group)
  262. #define TAU_GLOBAL_TIMER_EXTERNAL(timer)
  263. #define TAU_GLOBAL_TIMER_START(timer)
  264. #define TAU_GLOBAL_TIMER_STOP()
  265. #endif /* USE_TAU */
  266. /* Try to infer the endianness of the host based on compiler
  267. predefined macros. For systems on which the compiler does not
  268. define these macros, we rely on ppremake to define WORDS_BIGENDIAN
  269. correctly. For systems on which the compiler *does* define these
  270. macros, we ignore what ppremake said and define WORDS_BIGENDIAN
  271. correctly here. (This is essential on OSX, which requires
  272. compiling each file twice in different modes, for universal binary
  273. support.) */
  274. #if defined(__LITTLE_ENDIAN__) || defined(__i386__)
  275. #undef WORDS_BIGENDIAN
  276. #elif defined(__BIG_ENDIAN__) || defined(__ppc__)
  277. #undef WORDS_BIGENDIAN
  278. #define WORDS_BIGENDIAN 1
  279. #endif
  280. /* Try to determine if we're compiling in a 64-bit mode. */
  281. #ifdef __WORDSIZE
  282. #define NATIVE_WORDSIZE __WORDSIZE
  283. #elif defined(_LP64)
  284. #define NATIVE_WORDSIZE 64
  285. #else
  286. #define NATIVE_WORDSIZE 32
  287. #endif
  288. /* Some byte-alignment macros. */
  289. #ifdef CPPPARSER
  290. #define ALIGN_4BYTE
  291. #define ALIGN_8BYTE
  292. #define ALIGN_16BYTE
  293. #define ALIGN_64BYTE
  294. #elif defined(_MSC_VER)
  295. #define ALIGN_4BYTE __declspec(align(4))
  296. #define ALIGN_8BYTE __declspec(align(8))
  297. #define ALIGN_16BYTE __declspec(align(16))
  298. #define ALIGN_64BYTE __declspec(align(64))
  299. #elif defined(__GNUC__)
  300. #define ALIGN_4BYTE __attribute__ ((aligned (4)))
  301. #define ALIGN_8BYTE __attribute__ ((aligned (8)))
  302. #define ALIGN_16BYTE __attribute__ ((aligned (16)))
  303. #define ALIGN_64BYTE __attribute__ ((aligned (64)))
  304. #else
  305. #define ALIGN_4BYTE
  306. #define ALIGN_8BYTE
  307. #define ALIGN_16BYTE
  308. #endif
  309. // Do we need to implement memory-alignment enforcement within the MemoryHook
  310. // class, or will the underlying malloc implementation provide it
  311. // automatically?
  312. #if !defined(LINMATH_ALIGN)
  313. // We don't actually require any special memory-alignment beyond what the
  314. // underlying implementation is likely to provide anyway.
  315. #undef MEMORY_HOOK_DO_ALIGN
  316. #elif defined(USE_MEMORY_DLMALLOC)
  317. // This specialized malloc implementation can perform the required alignment.
  318. #undef MEMORY_HOOK_DO_ALIGN
  319. #elif defined(USE_MEMORY_PTMALLOC2)
  320. // But not this one. For some reason it crashes when we try to build it with
  321. // alignment 16. So if we're using ptmalloc2, we need to enforce alignment
  322. // externally.
  323. #define MEMORY_HOOK_DO_ALIGN 1
  324. #elif defined(IS_OSX) || defined(_WIN64)
  325. // The OS-provided malloc implementation will do the required alignment.
  326. #undef MEMORY_HOOK_DO_ALIGN
  327. #elif defined(MEMORY_HOOK_DO_ALIGN)
  328. // We need memory alignment, and we're willing to provide it ourselves.
  329. #else
  330. // We need memory alignment, and we haven't specified whether it should be
  331. // provided on top of the existing malloc library, or otherwise. Let's rely
  332. // on dlmalloc to provide it, it seems to be the most memory-efficient option.
  333. #define USE_MEMORY_DLMALLOC 1
  334. #endif
  335. /* Determine our memory-allocation requirements. */
  336. #if defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN)
  337. /* In this case we have some custom memory management requirements. */
  338. #else
  339. /* Otherwise, if we have no custom memory management needs at all, we
  340. might as well turn it all off and go straight to the OS-level
  341. calls. */
  342. #define USE_MEMORY_NOWRAPPERS 1
  343. #endif
  344. /* We must always use the STL allocator nowadays, because we have
  345. redefined the constructors for pvector, pmap, etc. */
  346. #define USE_STL_ALLOCATOR 1
  347. /*
  348. We define the macros BEGIN_PUBLISH and END_PUBLISH to bracket
  349. functions and global variable definitions that are to be published
  350. via interrogate to scripting languages. Also, the macro BLOCKING is
  351. used to flag any function or method that might perform I/O blocking
  352. and thus needs to release Python threads for its duration.
  353. */
  354. #ifdef CPPPARSER
  355. #define BEGIN_PUBLISH __begin_publish
  356. #define END_PUBLISH __end_publish
  357. #define BLOCKING __blocking
  358. #define MAKE_PROPERTY(property_name, ...) __make_property(property_name, __VA_ARGS__)
  359. #define MAKE_PROPERTY2(property_name, ...) __make_property2(property_name, __VA_ARGS__)
  360. #define MAKE_SEQ(seq_name, num_name, element_name) __make_seq(seq_name, num_name, element_name)
  361. #define MAKE_SEQ_PROPERTY(property_name, ...) __make_seq_property(property_name, __VA_ARGS__)
  362. #undef USE_STL_ALLOCATOR /* Don't try to parse these template classes in interrogate. */
  363. #define EXTENSION(x) __extension x
  364. #define EXTEND __extension
  365. #else
  366. #define BEGIN_PUBLISH
  367. #define END_PUBLISH
  368. #define BLOCKING
  369. #define MAKE_PROPERTY(property_name, ...)
  370. #define MAKE_PROPERTY2(property_name, ...)
  371. #define MAKE_SEQ(seq_name, num_name, element_name)
  372. #define MAKE_SEQ_PROPERTY(property_name, ...)
  373. #define EXTENSION(x)
  374. #define EXTEND
  375. #endif
  376. /* These symbols are used in dtoolsymbols.h and pandasymbols.h. */
  377. #if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
  378. #define EXPORT_CLASS __declspec(dllexport)
  379. #define IMPORT_CLASS __declspec(dllimport)
  380. #elif __GNUC__ >= 4 && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
  381. #define EXPORT_CLASS __attribute__((visibility("default")))
  382. #define IMPORT_CLASS
  383. #else
  384. #define EXPORT_CLASS
  385. #define IMPORT_CLASS
  386. #endif
  387. /* "extern template" is now part of the C++11 standard. */
  388. #if defined(CPPPARSER) || defined(LINK_ALL_STATIC)
  389. #define EXPORT_TEMPL
  390. #define IMPORT_TEMPL
  391. #elif defined(_MSC_VER)
  392. /* Nowadays, we'd define both of these as "extern" in all cases, so that
  393. the header file always marks the symbol as "extern" and the .cxx file
  394. explicitly instantiates it. However, MSVC versions before 2013 break
  395. the spec by explicitly disallowing it, so we have to instantiate the
  396. class from the header file. Fortunately, its linker is okay with the
  397. duplicate template instantiations that this causes. */
  398. #define EXPORT_TEMPL
  399. #define IMPORT_TEMPL extern
  400. #else
  401. #define EXPORT_TEMPL extern
  402. #define IMPORT_TEMPL extern
  403. #endif
  404. #ifdef __cplusplus
  405. #include "dtoolbase_cc.h"
  406. #endif
  407. #endif