1 #ifndef MEMORY_LIMITER_CLASS
2 #define MEMORY_LIMITER_CLASS
4 /*****************************************************************************\
6 * Name : memory_limiter *
7 * Author : Chris Koeritz *
9 *******************************************************************************
10 * Copyright (c) 2001-$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 \*****************************************************************************/
18 #include <basis/astring.h>
19 #include <basis/contracts.h>
20 #include <structures/set.h>
22 namespace structures {
25 class ml_memory_record;
26 class ml_memory_state_meter;
28 //! Tracks memory currently in use by memory manager objects.
30 The manager is given the ability to control overall memory usage as well
31 as to track memory usage per each user of the memory (assuming that the
32 memory is granted to unique users indexable via an integer).
38 memory_limiter(int overall_limit, int individual_limit);
39 //!< creates a limiter that allows "overall_limit" bytes to be in use.
40 /*!< any attempts to add new memory after that limit is reached will be
41 rejected. if "overall_limit" is zero, then no limit is enforced on the
42 amount of memory that can be used in total. the "individual_limit"
43 specifies per-user limits, where each user of memory is identified by a
44 unique integer and where all users are granted equal rights to allocate
45 memory. "individual_limit" can also be given as zero, meaning no limit
46 is enforced per individual. note that "overall_limit" should usually be
47 many multiples of the "individual_limit", as appropriate to how many users
50 virtual ~memory_limiter();
52 DEFINE_CLASS_NAME("memory_limiter");
54 int overall_limit() const { return _overall_limit; }
55 //!< returns the current overall limit.
56 int individual_limit() const { return _individual_limit; }
57 //!< returns the current individual limit.
59 int overall_usage() const { return _overall_size; }
60 //!< returns the size used by all managed memory.
62 int overall_space_left() const { return overall_limit() - overall_usage(); }
63 //!< returns the overall space left for allocation.
65 int individual_usage(int individual) const;
66 //!< returns the amount of memory used by "individual".
68 int individual_space_left(int individual) const;
69 //!< returns the space left for the individual specified.
71 basis::astring text_form(int indent = 0) const;
72 //!< returns a string that lists out the overall plus individual limits.
73 /*!< "indent" is used for spacing the printed rows of information. */
75 bool okay_allocation(int individual, int memory_desired);
76 //!< returns true if "individual" may allocate "memory_desired" bytes.
77 /*!< false indicates that this memory must not be allocated if the limits
78 are to be adhered to, either because there is already too much used in
79 the system at large or because this user is already using their limit. */
81 bool record_deletion(int individual, int memory_deleted);
82 //!< acknowledges that the "individual" freed "memory_deleted" bytes.
83 /*!< returns true if the "individual" is known and if "memory_deleted"
84 could be subtracted from that object's usage count. failure of this method
85 indicates that this class is not being used properly; if memory was
86 okayed to be granted in okay_allocation, then the paired record_deletion
87 will always succeed (in any arbitrary order where the okay_allocation
88 succeeds and proceeds the matching record_deletion). if there are no
89 remaining allocations for this individual, then its record is removed. */
92 //!< returns the object to a pristine state.
94 const structures::int_set &individuals_listed() const;
95 //!< reports the current set of individuals using memory.
96 /*!< to know whether one is using this class appropriately, check the
97 returned set. if one does not think there should be any memory in use,
98 then the set should be empty and overall_usage() should return zero.
99 if the overall_usage() is zero, but there are members in the set, then
100 there is an implementation error in memory_limiter. otherwise, if the
101 set is non-empty, then deleted memory has not been recorded. */
104 int _overall_limit; //!< how many total bytes allowed?
105 int _individual_limit; //!< how many bytes may each user consume?
106 int _overall_size; //!< the current measured overall memory usage in bytes.
107 ml_memory_state_meter *_individual_sizes; //!< tracks memory per individual.
109 ml_memory_record *find_individual(int individual) const;
110 //!< locates the record held for the "individual" specified or returns NULL_POINTER.