22 using namespace basis;
27 #define LOG(to_print) printf("%s\n", astring(to_print).s())
29 class ml_memory_record
34 ml_memory_record(
int initial) : _usage(initial) {}
39 class ml_memory_state_meter :
public int_hash<ml_memory_record>
42 ml_memory_state_meter() : int_hash<ml_memory_record>(10) {}
47 memory_limiter::memory_limiter(
int overall_limit,
int individual_limit)
48 : _overall_limit(overall_limit),
49 _individual_limit(individual_limit),
51 _individual_sizes(new ml_memory_state_meter)
57 WHACK(_individual_sizes);
63 _individual_sizes->reset();
67 {
return _individual_sizes->ids(); }
69 ml_memory_record *memory_limiter::find_individual(
int individual)
const
72 if (!_individual_sizes->find(individual, to_return))
return NULL_POINTER;
79 ml_memory_record *found = find_individual(individual);
102 to_return +=
astring(astring::SPRINTF,
"Overall Limit=%s, Allocations=%dK, "
106 int_set individuals = _individual_sizes->ids();
107 for (
int i = 0; i < individuals.
elements(); i++) {
112 astring(astring::SPRINTF,
"%dK",
115 to_return += indentat +
astring(astring::SPRINTF,
"individual %d: "
116 "Limit=%s, Used=%dK, Free=%s", individuals[i], allowed.
s(),
121 to_return += indentat +
"No allocations owned currently.";
132 && (_overall_size + memory_desired > _overall_limit) )
return false;
134 if (_individual_limit && (memory_desired > _individual_limit) )
return false;
136 ml_memory_record *found = find_individual(individual);
138 _individual_sizes->add(individual,
new ml_memory_record(0));
139 found = find_individual(individual);
141 LOG(
"ERROR: adding a new record to the memory state!");
145 if (_individual_limit
146 && (found->_usage + memory_desired > _individual_limit) )
148 found->_usage += memory_desired;
149 _overall_size += memory_desired;
155 if (memory_deleted < 0)
return false;
157 ml_memory_record *found = find_individual(individual);
158 if (!found)
return false;
160 if (found->_usage < memory_deleted)
return false;
162 found->_usage -= memory_deleted;
163 _overall_size -= memory_deleted;
165 if (!found->_usage) _individual_sizes->zap(individual);
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
A simple object that wraps a templated set of ints.
int individual_usage(int individual) const
returns the amount of memory used by "individual".
virtual ~memory_limiter()
int overall_space_left() const
returns the overall space left for allocation.
int overall_limit() const
returns the current overall limit.
bool okay_allocation(int individual, int memory_desired)
returns true if "individual" may allocate "memory_desired" bytes.
bool record_deletion(int individual, int memory_deleted)
acknowledges that the "individual" freed "memory_deleted" bytes.
int overall_usage() const
returns the size used by all managed memory.
int individual_limit() const
returns the current individual limit.
const structures::int_set & individuals_listed() const
reports the current set of individuals using memory.
basis::astring text_form(int indent=0) const
returns a string that lists out the overall plus individual limits.
int individual_space_left(int individual) const
returns the space left for the individual specified.
void reset()
returns the object to a pristine state.
int elements() const
Returns the number of elements in this set.
#define NULL_POINTER
The value representing a pointer to nothing.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
const int KILOBYTE
Number of bytes in a kilobyte.
A dynamic container class that holds any kind of object via pointers.