Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. #pragma once
  21.  
  22. #include <stdlib.h>
  23. #include <type_traits>
  24.  
  25. #ifdef __cplusplus
  26. #include <memory>
  27. #include "dxxsconf.h"
  28. #include "dsx-ns.h"
  29. #include <utility>
  30.  
  31. #define MEM_K 1.5       // Dynamic array growth factor
  32.  
  33. #ifdef DEBUG_BIAS_MEMORY_ALLOCATIONS
  34. #include <array>
  35. #define DXX_DEBUG_BIAS_MEMORY_ALLOCATION (sizeof(std::array<double, 2>))
  36. #else
  37. #define DXX_DEBUG_BIAS_MEMORY_ALLOCATION (0)
  38. #endif
  39.  
  40. namespace dcx {
  41.  
  42. #ifdef DEBUG_MEMORY_ALLOCATIONS
  43. void mem_init(void);
  44.  
  45. void mem_display_blocks();
  46. __attribute_alloc_size(1)
  47. __attribute_malloc()
  48. void *mem_malloc(size_t size, const char *var, const char *file, unsigned line);
  49. void * mem_calloc( size_t nmemb, size_t size, const char * var, const char * filename, unsigned line) __attribute_alloc_size(1,2) __attribute_malloc();
  50. __attribute_alloc_size(2)
  51. void *mem_realloc(void *buffer, size_t size, const char *var, const char *file, unsigned line);
  52. extern void mem_free( void * buffer );
  53.  
  54. /* DPH: Changed malloc, etc. to d_malloc. Overloading system calls is very evil and error prone */
  55.  
  56. // Checks to see if any blocks are overwritten
  57. void mem_validate_heap();
  58.  
  59. #define mem_calloc(nmemb,size,var,file,line)    ((mem_calloc)((size) ? (nmemb) : 0, (size), (var), (file), (line)))
  60.  
  61. #else
  62.  
  63. #ifdef DEBUG_BIAS_MEMORY_ALLOCATIONS
  64. #define bias_malloc(SIZE)       ({      \
  65.                 auto p = malloc((SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);     \
  66.                 p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
  67.         })
  68. /* Bias calloc wastes a bit extra to keep the math simple */
  69. #define bias_calloc(NMEMB,SIZE) ({      \
  70.                 auto p = calloc((NMEMB), (SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);    \
  71.                 p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
  72.         })
  73. #define bias_realloc(PTR,SIZE)  ({      \
  74.                 auto p = realloc(reinterpret_cast<char *>(PTR) - DXX_DEBUG_BIAS_MEMORY_ALLOCATION, (SIZE) + DXX_DEBUG_BIAS_MEMORY_ALLOCATION);  \
  75.                 p ? p + DXX_DEBUG_BIAS_MEMORY_ALLOCATION : p;   \
  76.         })
  77. #define bias_free(PTR)  free(reinterpret_cast<char *>(PTR) - DXX_DEBUG_BIAS_MEMORY_ALLOCATION)
  78. #else
  79. #define bias_malloc     malloc
  80. #define bias_calloc calloc
  81. #define bias_realloc realloc
  82. #define bias_free free
  83. #endif
  84.  
  85. #define mem_malloc(size,var,file,line)  ((void)var,(void)file,(void)line,bias_malloc((size)))
  86. #define mem_calloc(nmemb,size,var,file,line)    ((void)var,(void)file,(void)line,bias_calloc((nmemb),(size)))
  87. #define mem_realloc(ptr,size,var,file,line)     ((void)var,(void)file,(void)line,bias_realloc((ptr),(size)))
  88. #define mem_free        bias_free
  89.  
  90. static inline void mem_init(void)
  91. {
  92. }
  93. #endif
  94.  
  95. template <typename T>
  96. T *MALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
  97. {
  98.         static_assert(std::is_pod<T>::value, "MALLOC cannot allocate non-POD");
  99.         return r = reinterpret_cast<T *>(mem_malloc(count * sizeof(T), var, file, line));
  100. }
  101.  
  102. template <typename T>
  103. T *CALLOC(T *&r, std::size_t count, const char *var, const char *file, unsigned line)
  104. {
  105.         static_assert(std::is_pod<T>::value, "CALLOC cannot allocate non-POD");
  106.         return r = reinterpret_cast<T *>(mem_calloc(count, sizeof(T), var, file, line));
  107. }
  108.  
  109. #define d_malloc(size)      mem_malloc((size),"Unknown", __FILE__,__LINE__ )
  110. #define d_realloc(ptr,size) mem_realloc((ptr),(size),"Unknown", __FILE__,__LINE__ )
  111. template <typename T>
  112. static inline void d_free(T *&ptr)
  113. {
  114.         static_assert((std::is_same<T, void>::value || std::is_pod<T>::value), "d_free cannot free non-POD");
  115.         mem_free(std::exchange(ptr, nullptr));
  116. }
  117.  
  118. template <typename T>
  119. class RAIIdmem_deleter
  120. {
  121. public:
  122.         void operator()(T *v) const
  123.         {
  124.                 d_free(v);
  125.         }
  126. };
  127.  
  128. template <typename T>
  129. class RAIIdmem_deleter<T[]> : public RAIIdmem_deleter<T>
  130. {
  131. public:
  132.         typedef T *pointer;
  133. };
  134.  
  135. template <typename T>
  136. class RAIIdmem : public std::unique_ptr<T, RAIIdmem_deleter<T>>
  137. {
  138.         typedef std::unique_ptr<T, RAIIdmem_deleter<T>> base_ptr;
  139. public:
  140.         static_assert(std::is_pod<typename base_ptr::element_type>::value, "RAIIdmem cannot manage non-POD");
  141.         DXX_INHERIT_CONSTRUCTORS(RAIIdmem, base_ptr);
  142. };
  143.  
  144. /* Disallow C-style arrays of known bound.  Use RAIIdmem<std::array<T, N>>
  145.  * for this case.
  146.  */
  147. template <typename T, std::size_t N>
  148. class RAIIdmem<T[N]>
  149. {
  150. public:
  151.         RAIIdmem() = delete;
  152. };
  153.  
  154. template <typename T>
  155. RAIIdmem<T> &MALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
  156. {
  157.         typename RAIIdmem<T>::pointer p;
  158.         return r.reset(MALLOC<typename RAIIdmem<T>::element_type>(p, count, var, file, line)), r;
  159. }
  160.  
  161. template <typename T>
  162. RAIIdmem<T[]> &MALLOC(RAIIdmem<T[]> &r, const std::size_t count, const char *const var, const char *const file, const unsigned line)
  163. {
  164.         return MALLOC<T[]>(r, count, var, file, line);
  165. }
  166.  
  167. template <typename T>
  168. void CALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
  169. {
  170.         typename RAIIdmem<T>::pointer p;
  171.         r.reset(CALLOC<typename RAIIdmem<T>::element_type>(p, count, var, file, line));
  172. }
  173.  
  174. #define MALLOC( var, type, count )      (MALLOC<type>(var, (count),#var, __FILE__,__LINE__ ))
  175. #define CALLOC( var, type, count )      (CALLOC<type>(var, (count),#var, __FILE__,__LINE__ ))
  176.  
  177. }
  178.  
  179. #endif
  180.