feisty meow concerns codebase 2.140
static_memory_gremlin.h
Go to the documentation of this file.
1#ifndef STATIC_MEMORY_GREMLIN_CLASS
2#define STATIC_MEMORY_GREMLIN_CLASS
3
4/*****************************************************************************\
5* *
6* Name : static_memory_gremlin *
7* Author : Chris Koeritz *
8* *
9*******************************************************************************
10* Copyright (c) 1992-$now By Author. This program is free software; you can *
11* redistribute it and/or modify it under the terms of the GNU General Public *
12* License as published by the Free Software Foundation; either version 2 of *
13* the License or (at your option) any later version. This is online at: *
14* http://www.fsf.org/copyleft/gpl.html *
15* Please send any updates to: fred@gruntose.com *
16\*****************************************************************************/
17
18#include <basis/contracts.h>
19#include <basis/enhance_cpp.h>
20#include <basis/mutex.h>
21
22namespace structures {
23
24// forward declarations.
25class gremlin_object_record;
26
28
36{
37public:
39
49 DEFINE_CLASS_NAME("static_memory_gremlin");
50
51 static bool __program_is_dying();
53
60
65
66 void enable_debugging(bool verbose) { c_show_debugging = verbose; }
68
69 bool put(const char *unique_name, basis::root_object *ptr);
71
75 basis::root_object *get(const char *unique_name);
77
81 const char *find(const basis::root_object *ptr);
83
89private:
90 basis::mutex c_lock;
91 int c_top_index;
92 int c_actual_size;
93 gremlin_object_record **c_pointers;
94 bool c_show_debugging;
95
96 int locate(const char *unique_name);
98};
99
101
103
129#define SAFE_STATIC(type, func_name, parms) \
130 type &func_name() { SAFE_STATIC_IMPLEMENTATION(type, parms, __LINE__); }
131
133#define SAFE_STATIC_CONST(type, func_name, parms) \
134 const type &func_name() \
135 { SAFE_STATIC_IMPLEMENTATION(type, parms, __LINE__); }
136
138
143#define STATIC_STRING(str) \
144 SAFE_STATIC_IMPLEMENTATION(astring, (str), __LINE__)
145
147
149#define UNIQUE_NAME_BASED_ON_SOURCE(name, linenum) \
150 static const char *name = "file:" __FILE__ ":line:" #linenum
151
153
158#define SAFE_STATIC_IMPLEMENTATION(type, parms, linenum) \
159/*hmmm: bring all this back.*/ \
160/* const char *func = "allocation"; */ \
161/* frame_tracking_instance __trail_of_function("safe_static", func, \
162 __FILE__, __LINE__, true); */ \
163 UNIQUE_NAME_BASED_ON_SOURCE(__uid_name, linenum); \
164/* program_wide_memories(); */ \
165 static basis::root_object *_hidden = NULL_POINTER; \
166 /* if haven't initialized yet, then definitely need to lock carefully. */ \
167 if (structures::static_memory_gremlin::__program_is_dying() || !_hidden) { \
168 basis::auto_synchronizer l(structures::static_memory_gremlin::__memory_gremlin_synchronizer()); \
169 if (structures::static_memory_gremlin::__program_is_dying()) { \
170 /* we can't rely on the pointer since we're shutting down currently. */ \
171 _hidden = structures::static_memory_gremlin::__hoople_globals().get(__uid_name); \
172 } \
173 if (!_hidden) { /* make sure no one scooped us. */ \
174 /* try to retrieve an existing one first and use it if there. */ \
175 _hidden = structures::static_memory_gremlin::__hoople_globals().get(__uid_name); \
176 if (!_hidden) { \
177 _hidden = new type parms ; /* create the object finally. */ \
178 /* store our object using the unique name for it. */ \
179 if (!structures::static_memory_gremlin::__hoople_globals().put(__uid_name, _hidden)) { \
180 /* we failed to allocate space. this is serious. */ \
181 throw __uid_name; \
182 } \
183 } \
184 } \
185 } \
186 if (!_hidden) { \
187 /* grab the pointer that was stored, in case we're late getting here. */ \
188 /* another thread might have scooped the object creation. */ \
189 _hidden = structures::static_memory_gremlin::__hoople_globals().get(__uid_name); \
190 } \
191 return *dynamic_cast<type *>(_hidden)
192
193// historical note: the SAFE_STATIC approach has existed since about 1998.
194// however, the static_memory_gremlin's role in this started much later.
195
196} //namespace.
197
198#endif
199
Root object for any class that knows its own name.
Definition contracts.h:123
Holds onto memory chunks that are allocated globally within the program.
bool put(const char *unique_name, basis::root_object *ptr)
adds a "ptr" to the set of static objects under the "unique_name".
DEFINE_CLASS_NAME("static_memory_gremlin")
void enable_debugging(bool verbose)
if "verbose" is true, then the object will produce a noisy log.
basis::root_object * get(const char *unique_name)
locates the pointer held for the "unique_name", if any.
static bool __program_is_dying()
Reports whether the program is shutting down currently.
static static_memory_gremlin & __hoople_globals()
Holds onto objects that have been allocated in a program-wide scope.
static basis::mutex & __memory_gremlin_synchronizer()
private object for static_memory_gremlin's use only.
const char * find(const basis::root_object *ptr)
locates the name for "ptr" in our objects.
bool verbose
Definition makedep.cpp:112
A dynamic container class that holds any kind of object via pointers.
Definition amorph.h:55