00001 #ifndef STATIC_MEMORY_GREMLIN_CLASS
00002 #define STATIC_MEMORY_GREMLIN_CLASS
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "data_structure_dll.h"
00019
00020 #include <basis/callstack_tracker.h>
00021 #include <basis/memory_checker.h>
00022 #include <basis/mutex.h>
00023 #include <basis/portable.h>
00024
00025
00026 class object_base;
00027 class object_base_record;
00028
00030
00037 class DATA_STRUCTURE_CLASS_STYLE static_memory_gremlin
00038 {
00039 public:
00040 static_memory_gremlin();
00041
00042 ~static_memory_gremlin();
00051 void enable_debugging(bool verbose) { _show_debugging = verbose; }
00053
00054 bool put(const char *unique_name, object_base *ptr);
00056
00060 object_base *get(const char *unique_name);
00062
00066 const char *find(const object_base *ptr);
00068
00070 void ensure_space_exists();
00074 private:
00075 mutex *_lock;
00076 int _top_index;
00077 int _actual_size;
00078 object_base_record **_pointers_held;
00079 bool _show_debugging;
00080
00081 int locate(const char *unique_name);
00083 };
00084
00086
00087 bool DATA_STRUCTURE_FUNCTION_STYLE program_is_dying();
00089
00094 static_memory_gremlin DATA_STRUCTURE_FUNCTION_STYLE &HOOPLE_GLOBALS();
00096
00099
00100
00101 mutex DATA_STRUCTURE_FUNCTION_STYLE &__memory_gremlin_synchronizer();
00103
00113
00114
00115
00116
00117
00118 bool DATA_STRUCTURE_FUNCTION_STYLE program_is_dying();
00120
00121 const char DATA_STRUCTURE_FUNCTION_STYLE *EXCEPTION_INFO_FOR_SHUTTING_DOWN();
00123
00126
00127
00128
00129
00130
00131
00132
00134
00159 #define SAFE_STATIC(type, func_name, parms) \
00160 type &func_name() { SAFE_STATIC_IMPLEMENTATION(type, parms, __LINE__); }
00161
00163 #define SAFE_STATIC_CONST(type, func_name, parms) \
00164 const type &func_name() \
00165 { SAFE_STATIC_IMPLEMENTATION(type, parms, __LINE__); }
00166
00168
00173 #define STATIC_STRING(str) \
00174 SAFE_STATIC_IMPLEMENTATION(istring_object, (str), __LINE__)
00175
00177 #define UNIQUE_NAME_BASED_ON_SOURCE(name, linenum) \
00178 static const char *name = "file:" __FILE__ ":line:" #linenum
00179
00181
00186 #define SAFE_STATIC_IMPLEMENTATION(type, parms, linenum) \
00187 const char *func = "allocation"; \
00188 frame_tracking_instance __trail_of_function("safe_static", func, \
00189 __FILE__, __LINE__, true); \
00190 UNIQUE_NAME_BASED_ON_SOURCE(__uid_name, linenum); \
00191 program_wide_memories(); \
00192 static object_base *_hidden = NIL; \
00193 \
00194 if (program_is_dying() || !_hidden) { \
00195 auto_synchronizer l(__memory_gremlin_synchronizer()); \
00196 if (program_is_dying()) { \
00197 \
00198 _hidden = HOOPLE_GLOBALS().get(__uid_name); \
00199 } \
00200 if (!_hidden) { \
00201 \
00202 _hidden = HOOPLE_GLOBALS().get(__uid_name); \
00203 if (!_hidden) { \
00204 _hidden = new type parms ; \
00205 \
00206 if (!HOOPLE_GLOBALS().put(__uid_name, _hidden)) { \
00207 \
00208 throw __uid_name; \
00209 } \
00210 } \
00211 } \
00212 } \
00213 if (!_hidden) { \
00214 \
00215 \
00216 _hidden = HOOPLE_GLOBALS().get(__uid_name); \
00217 } \
00218 return *dynamic_cast<type *>(_hidden)
00219
00221
00223
00224 class DATA_STRUCTURE_CLASS_STYLE library_wide_cleanup
00225 {
00226 public:
00227 library_wide_cleanup();
00229
00230 ~library_wide_cleanup();
00231
00232 private:
00233 static_memory_gremlin *_shared_chunks;
00234 };
00235
00237
00239
00240 class DATA_STRUCTURE_CLASS_STYLE program_wide_cleanup
00241 {
00242 public:
00243 program_wide_cleanup();
00244 ~program_wide_cleanup();
00245 };
00246
00248
00249
00250
00251
00252
00253
00254
00255
00257
00259 #define HOOPLE_STARTUP_CODE_DLL \
00260 DEFINE_ARGC_AND_ARGV; \
00261 DEFINE_INSTANCE_HANDLE; \
00262 static library_wide_cleanup _jean_reno
00263
00265
00268 #define HOOPLE_STARTUP_CODE \
00269 HOOPLE_STARTUP_CODE_DLL; \
00270
00271 \
00272 static program_wide_cleanup _harvey_keitel
00273
00275 #define BASIS_STARTUP_CODE_DLL HOOPLE_STARTUP_CODE_DLL
00276 #define BASIS_STARTUP_CODE HOOPLE_STARTUP_CODE
00277
00278 #endif
00279