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 
22 namespace structures {
23 
24 // forward declarations.
25 class gremlin_object_record;
26 
28 
35 class static_memory_gremlin : public virtual basis::nameable
36 {
37 public:
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 
85  void ensure_space_exists();
89 private:
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