mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-26 08:41:47 -07:00
New public functions mps_pool_total_size and mps_pool_free_size.
Old (undocumented) functions mps_{mv,mvff,mvt}_size and mps_{mv,mvff,mvt}_free_size are now macros for the new public functions.
New pool methods PoolTotalSize and PoolFreeSize, with implementations for public pool classes except SNC.
Coverage of the new functions in apss and mpmss for the manual pool classes, and in finaltest for the automatic pool classes.
Copied from Perforce
Change: 186118
ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
7e22bed98f
commit
16ccef5e2d
24 changed files with 500 additions and 179 deletions
|
|
@ -41,9 +41,21 @@ static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size)
|
|||
}
|
||||
|
||||
|
||||
/* check_allocated_size -- check the allocated size of the pool */
|
||||
|
||||
static void check_allocated_size(mps_pool_t pool, mps_ap_t ap, size_t allocated)
|
||||
{
|
||||
size_t total = mps_pool_total_size(pool);
|
||||
size_t free = mps_pool_free_size(pool);
|
||||
size_t ap_free = (size_t)((char *)ap->limit - (char *)ap->init);
|
||||
Insist(total - free == allocated + ap_free);
|
||||
}
|
||||
|
||||
|
||||
/* stress -- create a pool of the requested type and allocate in it */
|
||||
|
||||
static mps_res_t stress(mps_arena_t arena, mps_align_t align,
|
||||
static mps_res_t stress(mps_arena_t arena, mps_pool_debug_option_s *options,
|
||||
mps_align_t align,
|
||||
size_t (*size)(size_t i, mps_align_t align),
|
||||
const char *name, mps_class_t class, mps_arg_s args[])
|
||||
{
|
||||
|
|
@ -53,6 +65,8 @@ static mps_res_t stress(mps_arena_t arena, mps_align_t align,
|
|||
size_t i, k;
|
||||
int *ps[testSetSIZE];
|
||||
size_t ss[testSetSIZE];
|
||||
size_t allocated = 0; /* Total allocated memory */
|
||||
size_t debugOverhead = options ? 2 * alignUp(options->fence_size, align) : 0;
|
||||
|
||||
printf("stress %s\n", name);
|
||||
|
||||
|
|
@ -66,8 +80,10 @@ static mps_res_t stress(mps_arena_t arena, mps_align_t align,
|
|||
res = make((mps_addr_t *)&ps[i], ap, ss[i]);
|
||||
if (res != MPS_RES_OK)
|
||||
goto allocFail;
|
||||
allocated += ss[i] + debugOverhead;
|
||||
if (ss[i] >= sizeof(ps[i]))
|
||||
*ps[i] = 1; /* Write something, so it gets swap. */
|
||||
check_allocated_size(pool, ap, allocated);
|
||||
}
|
||||
|
||||
mps_pool_check_fenceposts(pool);
|
||||
|
|
@ -90,6 +106,8 @@ static mps_res_t stress(mps_arena_t arena, mps_align_t align,
|
|||
mps_free(pool, (mps_addr_t)ps[i], ss[i]);
|
||||
/* if (i == testSetSIZE/2) */
|
||||
/* PoolDescribe((Pool)pool, mps_lib_stdout); */
|
||||
Insist(ss[i] + debugOverhead <= allocated);
|
||||
allocated -= ss[i] + debugOverhead;
|
||||
}
|
||||
/* allocate some new objects */
|
||||
for (i=testSetSIZE/2; i<testSetSIZE; ++i) {
|
||||
|
|
@ -97,7 +115,9 @@ static mps_res_t stress(mps_arena_t arena, mps_align_t align,
|
|||
res = make((mps_addr_t *)&ps[i], ap, ss[i]);
|
||||
if (res != MPS_RES_OK)
|
||||
goto allocFail;
|
||||
allocated += ss[i] + debugOverhead;
|
||||
}
|
||||
check_allocated_size(pool, ap, allocated);
|
||||
}
|
||||
|
||||
allocFail:
|
||||
|
|
@ -145,8 +165,8 @@ static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options)
|
|||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE);
|
||||
die(stress(arena, align, randomSizeAligned, "MVFF", mps_class_mvff(), args),
|
||||
"stress MVFF");
|
||||
die(stress(arena, NULL, align, randomSizeAligned, "MVFF",
|
||||
mps_class_mvff(), args), "stress MVFF");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
/* IWBN to test MVFFDebug, but the MPS doesn't support debugging APs, */
|
||||
|
|
@ -155,24 +175,23 @@ static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options)
|
|||
MPS_ARGS_BEGIN(args) {
|
||||
mps_align_t align = 1 << (rnd() % 6);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
|
||||
die(stress(arena, align, randomSizeAligned, "MV", mps_class_mv(), args),
|
||||
"stress MV");
|
||||
die(stress(arena, NULL, align, randomSizeAligned, "MV",
|
||||
mps_class_mv(), args), "stress MV");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
mps_align_t align = 1 << (rnd() % 6);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options);
|
||||
die(stress(arena, align, randomSizeAligned, "MV debug",
|
||||
mps_class_mv_debug(), args),
|
||||
"stress MV debug");
|
||||
die(stress(arena, options, align, randomSizeAligned, "MV debug",
|
||||
mps_class_mv_debug(), args), "stress MV debug");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
mps_align_t align = sizeof(void *) << (rnd() % 4);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
|
||||
die(stress(arena, align, randomSizeAligned, "MVT", mps_class_mvt(), args),
|
||||
"stress MVT");
|
||||
die(stress(arena, NULL, align, randomSizeAligned, "MVT",
|
||||
mps_class_mvt(), args), "stress MVT");
|
||||
} MPS_ARGS_END(args);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static mps_addr_t test_awl_find_dependent(mps_addr_t addr)
|
|||
static void *root[rootCOUNT];
|
||||
|
||||
static void test_trees(int mode, const char *name, mps_arena_t arena,
|
||||
mps_ap_t ap,
|
||||
mps_pool_t pool, mps_ap_t ap,
|
||||
mps_word_t (*make)(mps_word_t, mps_ap_t),
|
||||
void (*reg)(mps_word_t, mps_arena_t))
|
||||
{
|
||||
|
|
@ -158,7 +158,9 @@ static void test_trees(int mode, const char *name, mps_arena_t arena,
|
|||
|
||||
object_count = 0;
|
||||
|
||||
printf("Making some %s finalized trees of objects.\n", name);
|
||||
printf("---- Mode %s, pool class %s, %s trees ----\n",
|
||||
mode == ModePARK ? "PARK" : "POLL",
|
||||
pool->class->name, name);
|
||||
mps_arena_park(arena);
|
||||
|
||||
/* make some trees */
|
||||
|
|
@ -167,7 +169,6 @@ static void test_trees(int mode, const char *name, mps_arena_t arena,
|
|||
(*reg)((mps_word_t)root[i], arena);
|
||||
}
|
||||
|
||||
printf("Losing all pointers to the trees.\n");
|
||||
/* clean out the roots */
|
||||
for(i = 0; i < rootCOUNT; ++i) {
|
||||
root[i] = 0;
|
||||
|
|
@ -190,9 +191,15 @@ static void test_trees(int mode, const char *name, mps_arena_t arena,
|
|||
object_alloc = 0;
|
||||
while (object_alloc < 1000 && !mps_message_poll(arena))
|
||||
(void)DYLAN_INT(object_alloc++);
|
||||
printf(" Done.\n");
|
||||
break;
|
||||
}
|
||||
++ collections;
|
||||
{
|
||||
size_t live_size = (object_count - finals) * sizeof(void *) * 3;
|
||||
size_t alloc_size = mps_pool_total_size(pool) - mps_pool_free_size(pool);
|
||||
Insist(live_size <= alloc_size);
|
||||
}
|
||||
while (mps_message_poll(arena)) {
|
||||
mps_message_t message;
|
||||
mps_addr_t objaddr;
|
||||
|
|
@ -238,9 +245,9 @@ static void test_pool(int mode, mps_arena_t arena, mps_chain_t chain,
|
|||
"root_create\n");
|
||||
die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create\n");
|
||||
|
||||
test_trees(mode, "numbered", arena, ap, make_numbered_tree,
|
||||
test_trees(mode, "numbered", arena, pool, ap, make_numbered_tree,
|
||||
register_numbered_tree);
|
||||
test_trees(mode, "indirect", arena, ap, make_indirect_tree,
|
||||
test_trees(mode, "indirect", arena, pool, ap, make_indirect_tree,
|
||||
register_indirect_tree);
|
||||
|
||||
mps_ap_destroy(ap);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,9 @@ extern Res PoolAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr);
|
|||
extern void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
|
||||
void *v, size_t s);
|
||||
extern void PoolFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
|
||||
extern Size PoolTotalSize(Pool pool);
|
||||
extern Size PoolFreeSize(Pool pool);
|
||||
|
||||
extern Res PoolTrivInit(Pool pool, ArgList arg);
|
||||
extern void PoolTrivFinish(Pool pool);
|
||||
extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size,
|
||||
|
|
@ -275,6 +278,7 @@ extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step,
|
|||
extern void PoolTrivFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
|
||||
extern PoolDebugMixin PoolNoDebugMixin(Pool pool);
|
||||
extern BufferClass PoolNoBufferClass(void);
|
||||
extern Size PoolNoSize(Pool pool);
|
||||
|
||||
#define ClassOfPool(pool) ((pool)->class)
|
||||
#define SuperclassOfPool(pool) \
|
||||
|
|
|
|||
|
|
@ -23,9 +23,20 @@
|
|||
#define testLOOPS 10
|
||||
|
||||
|
||||
/* check_allocated_size -- check the allocated size of the pool */
|
||||
|
||||
static void check_allocated_size(mps_pool_t pool, size_t allocated)
|
||||
{
|
||||
size_t total = mps_pool_total_size(pool);
|
||||
size_t free = mps_pool_free_size(pool);
|
||||
Insist(total - free == allocated);
|
||||
}
|
||||
|
||||
|
||||
/* stress -- create a pool of the requested type and allocate in it */
|
||||
|
||||
static mps_res_t stress(mps_arena_t arena, size_t (*size)(size_t i),
|
||||
static mps_res_t stress(mps_arena_t arena, mps_pool_debug_option_s *options,
|
||||
size_t (*size)(size_t i), mps_align_t align,
|
||||
const char *name, mps_class_t pool_class,
|
||||
mps_arg_s *args)
|
||||
{
|
||||
|
|
@ -34,8 +45,10 @@ static mps_res_t stress(mps_arena_t arena, size_t (*size)(size_t i),
|
|||
size_t i, k;
|
||||
int *ps[testSetSIZE];
|
||||
size_t ss[testSetSIZE];
|
||||
size_t allocated = 0; /* Total allocated memory */
|
||||
size_t debugOverhead = options ? 2 * alignUp(options->fence_size, align) : 0;
|
||||
|
||||
printf("%s\n", name);
|
||||
printf("Pool class %s, alignment %u\n", name, (unsigned)align);
|
||||
|
||||
res = mps_pool_create_k(&pool, arena, pool_class, args);
|
||||
if (res != MPS_RES_OK)
|
||||
|
|
@ -48,8 +61,10 @@ static mps_res_t stress(mps_arena_t arena, size_t (*size)(size_t i),
|
|||
res = mps_alloc((mps_addr_t *)&ps[i], pool, ss[i]);
|
||||
if (res != MPS_RES_OK)
|
||||
return res;
|
||||
allocated += alignUp(ss[i], align) + debugOverhead;
|
||||
if (ss[i] >= sizeof(ps[i]))
|
||||
*ps[i] = 1; /* Write something, so it gets swap. */
|
||||
check_allocated_size(pool, allocated);
|
||||
}
|
||||
|
||||
mps_pool_check_fenceposts(pool);
|
||||
|
|
@ -72,13 +87,17 @@ static mps_res_t stress(mps_arena_t arena, size_t (*size)(size_t i),
|
|||
mps_free(pool, (mps_addr_t)ps[i], ss[i]);
|
||||
/* if (i == testSetSIZE/2) */
|
||||
/* PoolDescribe((Pool)pool, mps_lib_stdout); */
|
||||
Insist(alignUp(ss[i], align) + debugOverhead <= allocated);
|
||||
allocated -= alignUp(ss[i], align) + debugOverhead;
|
||||
}
|
||||
/* allocate some new objects */
|
||||
for (i=testSetSIZE/2; i<testSetSIZE; ++i) {
|
||||
ss[i] = (*size)(i);
|
||||
res = mps_alloc((mps_addr_t *)&ps[i], pool, ss[i]);
|
||||
if (res != MPS_RES_OK) return res;
|
||||
allocated += alignUp(ss[i], align) + debugOverhead;
|
||||
}
|
||||
check_allocated_size(pool, allocated);
|
||||
}
|
||||
|
||||
mps_pool_destroy(pool);
|
||||
|
|
@ -150,8 +169,8 @@ static void testInArena(mps_arena_class_t arena_class, mps_arg_s *arena_args,
|
|||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE);
|
||||
die(stress(arena, randomSize8, "MVFF", mps_class_mvff(), args),
|
||||
"stress MVFF");
|
||||
die(stress(arena, NULL, randomSize8, align, "MVFF",
|
||||
mps_class_mvff(), args), "stress MVFF");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
|
|
@ -161,31 +180,31 @@ static void testInArena(mps_arena_class_t arena_class, mps_arg_s *arena_args,
|
|||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options);
|
||||
die(stress(arena, randomSize8, "MVFF debug", mps_class_mvff_debug(), args),
|
||||
"stress MVFF debug");
|
||||
die(stress(arena, options, randomSize8, align, "MVFF debug",
|
||||
mps_class_mvff_debug(), args), "stress MVFF debug");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
mps_align_t align = 1 << (rnd() % 6);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
|
||||
die(stress(arena, randomSize, "MV", mps_class_mv(), args),
|
||||
"stress MV");
|
||||
die(stress(arena, NULL, randomSize, align, "MV",
|
||||
mps_class_mv(), args), "stress MV");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
mps_align_t align = 1 << (rnd() % 6);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options);
|
||||
die(stress(arena, randomSize, "MV debug", mps_class_mv_debug(), args),
|
||||
"stress MV debug");
|
||||
die(stress(arena, options, randomSize, align, "MV debug",
|
||||
mps_class_mv_debug(), args), "stress MV debug");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
fixedSizeSize = 1 + rnd() % 64;
|
||||
MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, fixedSizeSize);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, 100000);
|
||||
die(stress(arena, fixedSize, "MFS", mps_class_mfs(), args),
|
||||
"stress MFS");
|
||||
die(stress(arena, NULL, fixedSize, MPS_PF_ALIGN, "MFS",
|
||||
mps_class_mfs(), args), "stress MFS");
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
mps_arena_destroy(arena);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ typedef struct mps_class_s {
|
|||
PoolBufferClassMethod bufferClass; /* default BufferClass of pool */
|
||||
PoolDescribeMethod describe; /* describe the contents of the pool */
|
||||
PoolDebugMixinMethod debugMixin; /* find the debug mixin, if any */
|
||||
PoolSizeMethod totalSize; /* total memory allocated from arena */
|
||||
PoolSizeMethod freeSize; /* free memory (unused by client program) */
|
||||
Bool labelled; /* whether it has been EventLabelled */
|
||||
Sig sig; /* .class.end-sig */
|
||||
} PoolClassStruct;
|
||||
|
|
@ -136,6 +138,8 @@ typedef struct MFSStruct { /* MFS outer structure */
|
|||
Bool extendSelf; /* whether to allocate tracts */
|
||||
Size unitSize; /* rounded for management purposes */
|
||||
struct MFSHeaderStruct *freeList; /* head of the free list */
|
||||
Size total; /* total size allocated from arena */
|
||||
Size free; /* free space in pool */
|
||||
Tract tractList; /* the first tract */
|
||||
Sig sig; /* <design/sig/> */
|
||||
} MFSStruct;
|
||||
|
|
@ -158,7 +162,7 @@ typedef struct MVStruct { /* MV pool outer structure */
|
|||
Size extendBy; /* segment size to extend pool by */
|
||||
Size avgSize; /* client estimate of allocation size */
|
||||
Size maxSize; /* client estimate of maximum size */
|
||||
Size space; /* total free space in pool */
|
||||
Size free; /* free space in pool */
|
||||
Size lost; /* <design/poolmv/#lost> */
|
||||
RingStruct spans; /* span chain */
|
||||
Sig sig; /* <design/sig/> */
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ typedef void (*PoolFreeWalkMethod)(Pool pool, FreeBlockStepMethod f, void *p);
|
|||
typedef BufferClass (*PoolBufferClassMethod)(void);
|
||||
typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream);
|
||||
typedef PoolDebugMixin (*PoolDebugMixinMethod)(Pool pool);
|
||||
typedef Size (*PoolSizeMethod)(Pool pool);
|
||||
|
||||
|
||||
/* Messages
|
||||
|
|
|
|||
|
|
@ -472,6 +472,11 @@ extern mps_res_t mps_pool_create_v(mps_pool_t *, mps_arena_t,
|
|||
extern mps_res_t mps_pool_create_k(mps_pool_t *, mps_arena_t,
|
||||
mps_class_t, mps_arg_s []);
|
||||
extern void mps_pool_destroy(mps_pool_t);
|
||||
extern size_t mps_pool_total_size(mps_pool_t);
|
||||
extern size_t mps_pool_free_size(mps_pool_t);
|
||||
|
||||
|
||||
/* Chains */
|
||||
|
||||
/* .gen-param: This structure must match <code/chain.h#gen-param>. */
|
||||
typedef struct mps_gen_param_s {
|
||||
|
|
@ -483,6 +488,9 @@ extern mps_res_t mps_chain_create(mps_chain_t *, mps_arena_t,
|
|||
size_t, mps_gen_param_s *);
|
||||
extern void mps_chain_destroy(mps_chain_t);
|
||||
|
||||
|
||||
/* Manual Allocation */
|
||||
|
||||
extern mps_res_t mps_alloc(mps_addr_t *, mps_pool_t, size_t);
|
||||
extern mps_res_t mps_alloc_v(mps_addr_t *, mps_pool_t, size_t, va_list);
|
||||
extern void mps_free(mps_pool_t, mps_addr_t, size_t);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
#include "mps.h"
|
||||
|
||||
extern size_t mps_mv_free_size(mps_pool_t mps_pool);
|
||||
extern size_t mps_mv_size(mps_pool_t mps_pool);
|
||||
#define mps_mv_free_size(pool) (mps_pool_free_size(pool))
|
||||
#define mps_mv_size(pool) (mps_pool_total_size(pool))
|
||||
extern mps_class_t mps_class_mv(void);
|
||||
extern mps_class_t mps_class_mv_debug(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ extern const struct mps_key_s _mps_key_mvff_first_fit;
|
|||
#define MPS_KEY_MVFF_FIRST_FIT (&_mps_key_mvff_first_fit)
|
||||
#define MPS_KEY_MVFF_FIRST_FIT_FIELD b
|
||||
|
||||
extern size_t mps_mvff_free_size(mps_pool_t mps_pool);
|
||||
extern size_t mps_mvff_size(mps_pool_t mps_pool);
|
||||
#define mps_mvff_free_size(pool) (mps_pool_free_size(pool))
|
||||
#define mps_mvff_size(pool) (mps_pool_total_size(pool))
|
||||
extern mps_class_t mps_class_mvff(void);
|
||||
extern mps_class_t mps_class_mvff_debug(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,10 +34,12 @@ extern const struct mps_key_s _mps_key_mvt_frag_limit;
|
|||
*/
|
||||
extern mps_class_t mps_class_mvt(void);
|
||||
|
||||
/* The mvt pool class supports two extensions to the pool protocol:
|
||||
size and free_size. */
|
||||
extern size_t mps_mvt_free_size(mps_pool_t mps_pool);
|
||||
extern size_t mps_mvt_size(mps_pool_t mps_pool);
|
||||
/* The mvt pool class formerly supported two extensions to the pool
|
||||
protocol: size and free_size. These are deprecated in favour of the
|
||||
generic pool function. */
|
||||
|
||||
#define mps_mvt_free_size(pool) (mps_pool_free_size(pool))
|
||||
#define mps_mvt_size(pool) (mps_pool_total_size(pool))
|
||||
|
||||
#endif /* mpscmvt_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -678,6 +678,40 @@ void mps_pool_destroy(mps_pool_t pool)
|
|||
ArenaLeave(arena);
|
||||
}
|
||||
|
||||
size_t mps_pool_total_size(mps_pool_t pool)
|
||||
{
|
||||
Arena arena;
|
||||
Size size;
|
||||
|
||||
AVER(TESTT(Pool, pool));
|
||||
arena = PoolArena(pool);
|
||||
|
||||
ArenaEnter(arena);
|
||||
|
||||
size = PoolTotalSize(pool);
|
||||
|
||||
ArenaLeave(arena);
|
||||
|
||||
return (size_t)size;
|
||||
}
|
||||
|
||||
size_t mps_pool_free_size(mps_pool_t pool)
|
||||
{
|
||||
Arena arena;
|
||||
Size size;
|
||||
|
||||
AVER(TESTT(Pool, pool));
|
||||
arena = PoolArena(pool);
|
||||
|
||||
ArenaEnter(arena);
|
||||
|
||||
size = PoolFreeSize(pool);
|
||||
|
||||
ArenaLeave(arena);
|
||||
|
||||
return (size_t)size;
|
||||
}
|
||||
|
||||
|
||||
mps_res_t mps_alloc(mps_addr_t *p_o, mps_pool_t pool, size_t size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ Bool PoolClassCheck(PoolClass class)
|
|||
CHECKL(FUNCHECK(class->bufferClass));
|
||||
CHECKL(FUNCHECK(class->describe));
|
||||
CHECKL(FUNCHECK(class->debugMixin));
|
||||
CHECKL(FUNCHECK(class->totalSize));
|
||||
CHECKL(FUNCHECK(class->freeSize));
|
||||
CHECKS(PoolClass, class);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -521,6 +523,26 @@ void PoolFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
|
|||
}
|
||||
|
||||
|
||||
/* PoolTotalSize -- return total memory allocated from arena */
|
||||
|
||||
Size PoolTotalSize(Pool pool)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
|
||||
return (*pool->class->totalSize)(pool);
|
||||
}
|
||||
|
||||
|
||||
/* PoolFreeSize -- return free memory (unused by client program) */
|
||||
|
||||
Size PoolFreeSize(Pool pool)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
|
||||
return (*pool->class->freeSize)(pool);
|
||||
}
|
||||
|
||||
|
||||
/* PoolDescribe -- describe a pool */
|
||||
|
||||
Res PoolDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ DEFINE_CLASS(AbstractPoolClass, class)
|
|||
class->bufferClass = PoolNoBufferClass;
|
||||
class->describe = PoolTrivDescribe;
|
||||
class->debugMixin = PoolNoDebugMixin;
|
||||
class->totalSize = PoolNoSize;
|
||||
class->freeSize = PoolNoSize;
|
||||
class->labelled = FALSE;
|
||||
class->sig = PoolClassSig;
|
||||
}
|
||||
|
|
@ -696,6 +698,14 @@ BufferClass PoolNoBufferClass(void)
|
|||
}
|
||||
|
||||
|
||||
Size PoolNoSize(Pool pool)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
NOTREACHED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* C. COPYRIGHT AND LICENSE
|
||||
*
|
||||
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
||||
|
|
|
|||
|
|
@ -2266,6 +2266,50 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
|
|||
}
|
||||
|
||||
|
||||
/* AMCTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size AMCTotalSize(Pool pool)
|
||||
{
|
||||
AMC amc;
|
||||
Size size = 0;
|
||||
Ring node, nextNode;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
amc = Pool2AMC(pool);
|
||||
AVERT(AMC, amc);
|
||||
|
||||
RING_FOR(node, &amc->genRing, nextNode) {
|
||||
amcGen gen = RING_ELT(amcGen, amcRing, node);
|
||||
AVERT(amcGen, gen);
|
||||
size += gen->pgen.totalSize;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* AMCFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size AMCFreeSize(Pool pool)
|
||||
{
|
||||
AMC amc;
|
||||
Size size = 0;
|
||||
Ring node, nextNode;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
amc = Pool2AMC(pool);
|
||||
AVERT(AMC, amc);
|
||||
|
||||
RING_FOR(node, &amc->genRing, nextNode) {
|
||||
amcGen gen = RING_ELT(amcGen, amcRing, node);
|
||||
AVERT(amcGen, gen);
|
||||
size += gen->pgen.freeSize;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* AMCDescribe -- describe the contents of the AMC pool
|
||||
*
|
||||
* See <design/poolamc/#describe>.
|
||||
|
|
@ -2365,6 +2409,8 @@ DEFINE_POOL_CLASS(AMCZPoolClass, this)
|
|||
this->addrObject = AMCAddrObject;
|
||||
this->walk = AMCWalk;
|
||||
this->bufferClass = amcBufClassGet;
|
||||
this->totalSize = AMCTotalSize;
|
||||
this->freeSize = AMCFreeSize;
|
||||
this->describe = AMCDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1658,6 +1658,34 @@ static void AMSFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
|
|||
}
|
||||
|
||||
|
||||
/* AMSTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size AMSTotalSize(Pool pool)
|
||||
{
|
||||
AMS ams;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
ams = Pool2AMS(pool);
|
||||
AVERT(AMS, ams);
|
||||
|
||||
return ams->pgen.totalSize;
|
||||
}
|
||||
|
||||
|
||||
/* AMSFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size AMSFreeSize(Pool pool)
|
||||
{
|
||||
AMS ams;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
ams = Pool2AMS(pool);
|
||||
AVERT(AMS, ams);
|
||||
|
||||
return ams->pgen.freeSize;
|
||||
}
|
||||
|
||||
|
||||
/* AMSDescribe -- the pool class description method
|
||||
*
|
||||
* Iterates over the segments, describing all of them.
|
||||
|
|
@ -1729,6 +1757,8 @@ DEFINE_CLASS(AMSPoolClass, this)
|
|||
this->reclaim = AMSReclaim;
|
||||
this->walk = PoolNoWalk; /* TODO: job003738 */
|
||||
this->freewalk = AMSFreeWalk;
|
||||
this->totalSize = AMSTotalSize;
|
||||
this->freeSize = AMSFreeSize;
|
||||
this->describe = AMSDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1281,6 +1281,34 @@ static void AWLWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
|
|||
}
|
||||
|
||||
|
||||
/* AWLTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size AWLTotalSize(Pool pool)
|
||||
{
|
||||
AWL awl;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
awl = Pool2AWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
|
||||
return awl->pgen.totalSize;
|
||||
}
|
||||
|
||||
|
||||
/* AWLFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size AWLFreeSize(Pool pool)
|
||||
{
|
||||
AWL awl;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
awl = Pool2AWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
|
||||
return awl->pgen.freeSize;
|
||||
}
|
||||
|
||||
|
||||
/* AWLPoolClass -- the class definition */
|
||||
|
||||
DEFINE_POOL_CLASS(AWLPoolClass, this)
|
||||
|
|
@ -1305,6 +1333,8 @@ DEFINE_POOL_CLASS(AWLPoolClass, this)
|
|||
this->fixEmergency = AWLFix;
|
||||
this->reclaim = AWLReclaim;
|
||||
this->walk = AWLWalk;
|
||||
this->totalSize = AWLTotalSize;
|
||||
this->freeSize = AWLFreeSize;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -797,6 +797,34 @@ static void LOReclaim(Pool pool, Trace trace, Seg seg)
|
|||
}
|
||||
|
||||
|
||||
/* LOTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size LOTotalSize(Pool pool)
|
||||
{
|
||||
LO lo;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
lo = PoolPoolLO(pool);
|
||||
AVERT(LO, lo);
|
||||
|
||||
return lo->pgen.totalSize;
|
||||
}
|
||||
|
||||
|
||||
/* LOFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size LOFreeSize(Pool pool)
|
||||
{
|
||||
LO lo;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
lo = PoolPoolLO(pool);
|
||||
AVERT(LO, lo);
|
||||
|
||||
return lo->pgen.freeSize;
|
||||
}
|
||||
|
||||
|
||||
/* LOPoolClass -- the class definition */
|
||||
|
||||
DEFINE_POOL_CLASS(LOPoolClass, this)
|
||||
|
|
@ -817,6 +845,8 @@ DEFINE_POOL_CLASS(LOPoolClass, this)
|
|||
this->fixEmergency = LOFix;
|
||||
this->reclaim = LOReclaim;
|
||||
this->walk = LOWalk;
|
||||
this->totalSize = LOTotalSize;
|
||||
this->freeSize = LOFreeSize;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ static Res MFSInit(Pool pool, ArgList args)
|
|||
mfs->unitSize = unitSize;
|
||||
mfs->freeList = NULL;
|
||||
mfs->tractList = NULL;
|
||||
mfs->total = 0;
|
||||
mfs->free = 0;
|
||||
mfs->sig = MFSSig;
|
||||
|
||||
AVERT(MFS, mfs);
|
||||
|
|
@ -197,6 +199,10 @@ void MFSExtend(Pool pool, Addr base, Size size)
|
|||
TractSetP(tract, (void *)mfs->tractList);
|
||||
mfs->tractList = tract;
|
||||
|
||||
/* Update accounting */
|
||||
mfs->total += size;
|
||||
mfs->free += size;
|
||||
|
||||
/* Sew together all the new empty units in the region, working down */
|
||||
/* from the top so that they are in ascending order of address on the */
|
||||
/* free list. */
|
||||
|
|
@ -270,6 +276,7 @@ static Res MFSAlloc(Addr *pReturn, Pool pool, Size size,
|
|||
/* Detach the first free unit from the free list and return its address. */
|
||||
|
||||
mfs->freeList = f->next;
|
||||
mfs->free -= mfs->unitSize;
|
||||
|
||||
*pReturn = (Addr)f;
|
||||
return ResOK;
|
||||
|
|
@ -298,6 +305,35 @@ static void MFSFree(Pool pool, Addr old, Size size)
|
|||
h = (Header)old;
|
||||
h->next = mfs->freeList;
|
||||
mfs->freeList = h;
|
||||
mfs->free += mfs->unitSize;
|
||||
}
|
||||
|
||||
|
||||
/* MFSTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size MFSTotalSize(Pool pool)
|
||||
{
|
||||
MFS mfs;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mfs = PoolPoolMFS(pool);
|
||||
AVERT(MFS, mfs);
|
||||
|
||||
return mfs->total;
|
||||
}
|
||||
|
||||
|
||||
/* MFSFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size MFSFreeSize(Pool pool)
|
||||
{
|
||||
MFS mfs;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mfs = PoolPoolMFS(pool);
|
||||
AVERT(MFS, mfs);
|
||||
|
||||
return mfs->free;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -336,6 +372,8 @@ DEFINE_POOL_CLASS(MFSPoolClass, this)
|
|||
this->finish = MFSFinish;
|
||||
this->alloc = MFSAlloc;
|
||||
this->free = MFSFree;
|
||||
this->totalSize = MFSTotalSize;
|
||||
this->freeSize = MFSFreeSize;
|
||||
this->describe = MFSDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
@ -370,6 +408,8 @@ Bool MFSCheck(MFS mfs)
|
|||
if(mfs->tractList != NULL) {
|
||||
CHECKD_NOSIG(Tract, mfs->tractList);
|
||||
}
|
||||
CHECKL(mfs->free <= mfs->total);
|
||||
CHECKL((mfs->total - mfs->free) % mfs->unitSize == 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ typedef struct MVSpanStruct {
|
|||
MVBlockStruct base; /* sentinel at base of span */
|
||||
MVBlockStruct limit; /* sentinel at limit of span */
|
||||
MVBlock blocks; /* allocated blocks */
|
||||
Size space; /* total free space in span */
|
||||
Size free; /* free space in span */
|
||||
Size largest; /* .design.largest */
|
||||
Bool largestKnown; /* .design.largest */
|
||||
unsigned blockCount; /* number of blocks on chain */
|
||||
|
|
@ -160,11 +160,11 @@ static Bool MVSpanCheck(MVSpan span)
|
|||
/* The sentinels mustn't overlap. */
|
||||
CHECKL(span->base.limit <= span->limit.base);
|
||||
/* The free space can't be more than the gap between the sentinels. */
|
||||
CHECKL(span->space <= SpanInsideSentinels(span));
|
||||
CHECKL(span->free <= SpanInsideSentinels(span));
|
||||
|
||||
CHECKL(BoolCheck(span->largestKnown));
|
||||
if (span->largestKnown) { /* .design.largest */
|
||||
CHECKL(span->largest <= span->space);
|
||||
CHECKL(span->largest <= span->free);
|
||||
/* at least this much is free */
|
||||
} else {
|
||||
CHECKL(span->largest == SpanSize(span)+1);
|
||||
|
|
@ -277,7 +277,7 @@ static Res MVInit(Pool pool, ArgList args)
|
|||
mv->maxSize = maxSize;
|
||||
RingInit(&mv->spans);
|
||||
|
||||
mv->space = 0;
|
||||
mv->free = 0;
|
||||
mv->lost = 0;
|
||||
|
||||
mv->sig = MVSig;
|
||||
|
|
@ -368,7 +368,7 @@ static Bool MVSpanAlloc(Addr *addrReturn, MVSpan span, Size size,
|
|||
span->largest = SpanSize(span) + 1; /* .design.largest */
|
||||
}
|
||||
|
||||
span->space -= size;
|
||||
span->free -= size;
|
||||
*addrReturn = new;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -484,7 +484,7 @@ static Res MVSpanFree(MVSpan span, Addr base, Addr limit, Pool blockPool)
|
|||
|
||||
AVERT(MVBlock, block);
|
||||
|
||||
span->space += AddrOffset(base, limit);
|
||||
span->free += AddrOffset(base, limit);
|
||||
|
||||
if (freeAreaSize > span->largest) { /* .design.largest */
|
||||
AVER(span->largestKnown);
|
||||
|
|
@ -528,16 +528,16 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
|
|||
|
||||
size = SizeAlignUp(size, pool->alignment);
|
||||
|
||||
if(size <= mv->space) {
|
||||
if(size <= mv->free) {
|
||||
spans = &mv->spans;
|
||||
RING_FOR(node, spans, nextNode) {
|
||||
span = RING_ELT(MVSpan, spans, node);
|
||||
if((size <= span->largest) && /* .design.largest.alloc */
|
||||
(size <= span->space)) {
|
||||
(size <= span->free)) {
|
||||
Addr new;
|
||||
|
||||
if(MVSpanAlloc(&new, span, size, mvBlockPool(mv))) {
|
||||
mv->space -= size;
|
||||
mv->free -= size;
|
||||
AVER(AddrIsAligned(new, pool->alignment));
|
||||
*pReturn = new;
|
||||
return ResOK;
|
||||
|
|
@ -593,20 +593,20 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
|
|||
RingInit(&span->spans);
|
||||
span->base.base = span->base.limit = base;
|
||||
span->limit.base = span->limit.limit = limit;
|
||||
span->space = AddrOffset(span->base.limit, span->limit.base);
|
||||
span->free = AddrOffset(span->base.limit, span->limit.base);
|
||||
span->limit.next = NULL;
|
||||
span->base.next = &span->limit;
|
||||
span->blocks = &span->base;
|
||||
span->blockCount = 2;
|
||||
span->base.limit = AddrAdd(span->base.limit, size);
|
||||
span->space -= size;
|
||||
span->largest = span->space;
|
||||
span->free -= size;
|
||||
span->largest = span->free;
|
||||
span->largestKnown = TRUE;
|
||||
|
||||
span->sig = MVSpanSig;
|
||||
AVERT(MVSpan, span);
|
||||
|
||||
mv->space += span->space;
|
||||
mv->free += span->free;
|
||||
RingInsert(&mv->spans, &span->spans);
|
||||
/* use RingInsert so that we examine this new span first when allocating */
|
||||
|
||||
|
|
@ -655,16 +655,16 @@ static void MVFree(Pool pool, Addr old, Size size)
|
|||
if(res != ResOK)
|
||||
mv->lost += size;
|
||||
else
|
||||
mv->space += size;
|
||||
mv->free += size;
|
||||
|
||||
/* free space should be less than total space */
|
||||
AVER(span->space <= SpanInsideSentinels(span));
|
||||
if(span->space == SpanSize(span)) { /* the whole span is free */
|
||||
AVER(span->free <= SpanInsideSentinels(span));
|
||||
if(span->free == SpanSize(span)) { /* the whole span is free */
|
||||
AVER(span->blockCount == 2);
|
||||
/* both blocks are the trivial sentinel blocks */
|
||||
AVER(span->base.limit == span->base.base);
|
||||
AVER(span->limit.limit == span->limit.base);
|
||||
mv->space -= span->space;
|
||||
mv->free -= span->free;
|
||||
ArenaFree(TractBase(span->tract), span->size, pool);
|
||||
RingRemove(&span->spans);
|
||||
RingFinish(&span->spans);
|
||||
|
|
@ -687,6 +687,51 @@ static PoolDebugMixin MVDebugMixin(Pool pool)
|
|||
}
|
||||
|
||||
|
||||
/* MVTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size MVTotalSize(Pool pool)
|
||||
{
|
||||
MV mv;
|
||||
Size size = 0;
|
||||
Ring node, next;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mv = Pool2MV(pool);
|
||||
AVERT(MV, mv);
|
||||
|
||||
RING_FOR(node, &mv->spans, next) {
|
||||
MVSpan span = RING_ELT(MVSpan, spans, node);
|
||||
AVERT(MVSpan, span);
|
||||
size += span->size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* MVFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size MVFreeSize(Pool pool)
|
||||
{
|
||||
MV mv;
|
||||
Size size = 0;
|
||||
Ring node, next;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mv = Pool2MV(pool);
|
||||
AVERT(MV, mv);
|
||||
|
||||
RING_FOR(node, &mv->spans, next) {
|
||||
MVSpan span = RING_ELT(MVSpan, spans, node);
|
||||
AVERT(MVSpan, span);
|
||||
size += span->free;
|
||||
}
|
||||
|
||||
AVER(size == mv->free + mv->lost);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static Res MVDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
{
|
||||
Res res;
|
||||
|
|
@ -710,7 +755,8 @@ static Res MVDescribe(Pool pool, mps_lib_FILE *stream)
|
|||
" extendBy $W\n", (WriteFW)mv->extendBy,
|
||||
" avgSize $W\n", (WriteFW)mv->avgSize,
|
||||
" maxSize $W\n", (WriteFW)mv->maxSize,
|
||||
" space $P\n", (WriteFP)mv->space,
|
||||
" free $W\n", (WriteFP)mv->free,
|
||||
" lost $W\n", (WriteFP)mv->lost,
|
||||
NULL);
|
||||
if(res != ResOK) return res;
|
||||
|
||||
|
|
@ -725,7 +771,8 @@ static Res MVDescribe(Pool pool, mps_lib_FILE *stream)
|
|||
res = WriteF(stream,
|
||||
" span $P", (WriteFP)span,
|
||||
" tract $P", (WriteFP)span->tract,
|
||||
" space $W", (WriteFW)span->space,
|
||||
" size $W", (WriteFW)span->size,
|
||||
" free $W", (WriteFW)span->free,
|
||||
" blocks $U", (WriteFU)span->blockCount,
|
||||
" largest ",
|
||||
NULL);
|
||||
|
|
@ -806,6 +853,8 @@ DEFINE_POOL_CLASS(MVPoolClass, this)
|
|||
this->finish = MVFinish;
|
||||
this->alloc = MVAlloc;
|
||||
this->free = MVFree;
|
||||
this->totalSize = MVTotalSize;
|
||||
this->freeSize = MVFreeSize;
|
||||
this->describe = MVDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
@ -847,58 +896,6 @@ mps_class_t mps_class_mv_debug(void)
|
|||
}
|
||||
|
||||
|
||||
/* mps_mv_free_size -- free bytes in pool */
|
||||
|
||||
size_t mps_mv_free_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MV mv;
|
||||
MVSpan span;
|
||||
Size f = 0;
|
||||
Ring spans, node = NULL, nextNode; /* gcc whinge stop */
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mv = Pool2MV(pool);
|
||||
AVERT(MV, mv);
|
||||
|
||||
spans = &mv->spans;
|
||||
RING_FOR(node, spans, nextNode) {
|
||||
span = RING_ELT(MVSpan, spans, node);
|
||||
AVERT(MVSpan, span);
|
||||
f += span->space;
|
||||
}
|
||||
|
||||
return (size_t)f;
|
||||
}
|
||||
|
||||
|
||||
size_t mps_mv_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MV mv;
|
||||
MVSpan span;
|
||||
Size f = 0;
|
||||
Ring spans, node = NULL, nextNode; /* gcc whinge stop */
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mv = Pool2MV(pool);
|
||||
AVERT(MV, mv);
|
||||
|
||||
spans = &mv->spans;
|
||||
RING_FOR(node, spans, nextNode) {
|
||||
span = RING_ELT(MVSpan, spans, node);
|
||||
AVERT(MVSpan, span);
|
||||
f += span->size;
|
||||
}
|
||||
|
||||
return (size_t)f;
|
||||
}
|
||||
|
||||
|
||||
/* MVCheck -- check the consistency of an MV structure */
|
||||
|
||||
Bool MVCheck(MV mv)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ static Res MVTBufferFill(Addr *baseReturn, Addr *limitReturn,
|
|||
static void MVTBufferEmpty(Pool pool, Buffer buffer, Addr base, Addr limit);
|
||||
static void MVTFree(Pool pool, Addr base, Size size);
|
||||
static Res MVTDescribe(Pool pool, mps_lib_FILE *stream);
|
||||
static Size MVTTotalSize(Pool pool);
|
||||
static Size MVTFreeSize(Pool pool);
|
||||
static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size,
|
||||
Bool withReservoirPermit);
|
||||
|
||||
|
|
@ -146,6 +148,8 @@ DEFINE_POOL_CLASS(MVTPoolClass, this)
|
|||
this->free = MVTFree;
|
||||
this->bufferFill = MVTBufferFill;
|
||||
this->bufferEmpty = MVTBufferEmpty;
|
||||
this->totalSize = MVTTotalSize;
|
||||
this->freeSize = MVTFreeSize;
|
||||
this->describe = MVTDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
@ -993,6 +997,34 @@ static void MVTFree(Pool pool, Addr base, Size size)
|
|||
}
|
||||
|
||||
|
||||
/* MVTTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size MVTTotalSize(Pool pool)
|
||||
{
|
||||
MVT mvt;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvt = Pool2MVT(pool);
|
||||
AVERT(MVT, mvt);
|
||||
|
||||
return mvt->size;
|
||||
}
|
||||
|
||||
|
||||
/* MVTFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size MVTFreeSize(Pool pool)
|
||||
{
|
||||
MVT mvt;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvt = Pool2MVT(pool);
|
||||
AVERT(MVT, mvt);
|
||||
|
||||
return mvt->available + mvt->unavailable;
|
||||
}
|
||||
|
||||
|
||||
/* MVTDescribe -- describe an MVT pool */
|
||||
|
||||
static Res MVTDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
|
|
@ -1093,44 +1125,6 @@ mps_class_t mps_class_mvt(void)
|
|||
}
|
||||
|
||||
|
||||
/* MPS Interface extensions --- should these be pool generics? */
|
||||
|
||||
|
||||
/* mps_mvt_size -- number of bytes committed to the pool */
|
||||
|
||||
size_t mps_mvt_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MVT mvt;
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvt = Pool2MVT(pool);
|
||||
AVERT(MVT, mvt);
|
||||
|
||||
return (size_t)mvt->size;
|
||||
}
|
||||
|
||||
|
||||
/* mps_mvt_free_size -- number of bytes comitted to the pool that are
|
||||
* available for allocation
|
||||
*/
|
||||
size_t mps_mvt_free_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MVT mvt;
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvt = Pool2MVT(pool);
|
||||
AVERT(MVT, mvt);
|
||||
|
||||
return (size_t)mvt->available;
|
||||
}
|
||||
|
||||
|
||||
/* Internal methods */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -639,6 +639,34 @@ static PoolDebugMixin MVFFDebugMixin(Pool pool)
|
|||
}
|
||||
|
||||
|
||||
/* MVFFTotalSize -- total memory allocated from the arena */
|
||||
|
||||
static Size MVFFTotalSize(Pool pool)
|
||||
{
|
||||
MVFF mvff;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvff = Pool2MVFF(pool);
|
||||
AVERT(MVFF, mvff);
|
||||
|
||||
return LandSize(MVFFTotalCBS(mvff));
|
||||
}
|
||||
|
||||
|
||||
/* MVFFFreeSize -- free memory (unused by client program) */
|
||||
|
||||
static Size MVFFFreeSize(Pool pool)
|
||||
{
|
||||
MVFF mvff;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
mvff = Pool2MVFF(pool);
|
||||
AVERT(MVFF, mvff);
|
||||
|
||||
return LandSize(MVFFFailover(mvff));
|
||||
}
|
||||
|
||||
|
||||
/* MVFFDescribe -- describe an MVFF pool */
|
||||
|
||||
static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
|
|
@ -695,6 +723,8 @@ DEFINE_POOL_CLASS(MVFFPoolClass, this)
|
|||
this->free = MVFFFree;
|
||||
this->bufferFill = MVFFBufferFill;
|
||||
this->bufferEmpty = MVFFBufferEmpty;
|
||||
this->totalSize = MVFFTotalSize;
|
||||
this->freeSize = MVFFFreeSize;
|
||||
this->describe = MVFFDescribe;
|
||||
AVERT(PoolClass, this);
|
||||
}
|
||||
|
|
@ -734,37 +764,6 @@ mps_class_t mps_class_mvff_debug(void)
|
|||
}
|
||||
|
||||
|
||||
/* Total free bytes. See <design/poolmvff/#design.arena-enter> */
|
||||
|
||||
size_t mps_mvff_free_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MVFF mvff;
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
AVERT(Pool, pool);
|
||||
mvff = Pool2MVFF(pool);
|
||||
AVERT(MVFF, mvff);
|
||||
|
||||
return (size_t)LandSize(MVFFFailover(mvff));
|
||||
}
|
||||
|
||||
/* Total owned bytes. See <design/poolmvff/#design.arena-enter> */
|
||||
|
||||
size_t mps_mvff_size(mps_pool_t mps_pool)
|
||||
{
|
||||
Pool pool;
|
||||
MVFF mvff;
|
||||
|
||||
pool = (Pool)mps_pool;
|
||||
AVERT(Pool, pool);
|
||||
mvff = Pool2MVFF(pool);
|
||||
AVERT(MVFF, mvff);
|
||||
|
||||
return (size_t)LandSize(MVFFTotalCBS(mvff));
|
||||
}
|
||||
|
||||
|
||||
/* MVFFCheck -- check the consistency of an MVFF structure */
|
||||
|
||||
ATTRIBUTE_UNUSED
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
SRCID(poolsnc, "$Id$");
|
||||
|
||||
|
||||
#define SNCGen ((Serial)1) /* "generation" for SNC pools */
|
||||
|
||||
|
||||
/* SNCStruct -- structure for an SNC pool
|
||||
*
|
||||
* See design.mps.poolsnc.poolstruct.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ New features
|
|||
was considered, and a chain was collected up to, but not including,
|
||||
the lowest generation whose new size was within its capacity.)
|
||||
|
||||
#. New pool introspection functions :c:func:`mps_pool_total_size` and
|
||||
:c:func:`mps_pool_free_size`.
|
||||
|
||||
|
||||
Interface changes
|
||||
.................
|
||||
|
|
|
|||
|
|
@ -135,6 +135,31 @@ See the :ref:`pool` for a list of pool classes.
|
|||
Pool introspection
|
||||
------------------
|
||||
|
||||
.. c:function:: size_t mps_pool_total_size(mps_pool_t pool)
|
||||
|
||||
Return the total memory allocated from the arena and managed by
|
||||
the pool.
|
||||
|
||||
``pool`` is the pool.
|
||||
|
||||
The result includes memory in use by the client program, memory
|
||||
that's available for use by the client program, and memory
|
||||
that's lost to fragmentation. It does not include memory used by
|
||||
the pool's internal control structures.
|
||||
|
||||
|
||||
.. c:function:: size_t mps_pool_free_size(mps_pool_t pool)
|
||||
|
||||
Return the free memory: memory managed by the pool but not in use
|
||||
by the client program.
|
||||
|
||||
``pool`` is the pool.
|
||||
|
||||
The result includes memory that's available for use by the client
|
||||
program, and memory that's lost to fragmentation. It does not
|
||||
include memory used by the pool's internal control structures.
|
||||
|
||||
|
||||
.. c:function:: mps_bool_t mps_addr_pool(mps_pool_t *pool_o, mps_arena_t arena, mps_addr_t addr)
|
||||
|
||||
Determine the :term:`pool` to which an address belongs.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue