M
Michael B Allen
Here's fragment of C from an allocator. This allocator permits the user
to specify a callback to reclaim memory if necessary. If memory cannot be
found the 'if (reclaim)' block is entered and the callback is called.
However, I would like to implement some kind of barrier that prevents the
callback from calling suba_alloc recusively. One recursive call is ok,
but if memory isn't found a second time, chances are good an infinate
loop will occur.
So how can I limit this recursive call? Below I have devised a method of
saving the address of an object on the first call reasoning that
subsiquent calls cannot reuse the same address but this is a poor
solution as it is difficult to reset the reclaim_barrier to NULL.
Does any else have a simple solution to limit this recursive call in the
way I've described?
void *
suba_alloc(struct allocator *suba, size_t size, int zero)
{
int reclaim = 0;
again:
if (reclaim) {
if (suba->reclaim_barrier == NULL) {
suba->reclaim_barrier = &reclaim;
}
if (suba->reclaim == NULL || suba->reclaim_barrier != &reclaim ||
suba->reclaim(suba, suba->reclaim_arg, reclaim) == 0) {
errno = ENOMEM;
return NULL;
}
}
if (can't find memory) {
reclaim++;
goto again;
}
return the memory;
}
Thanks,
Mike
to specify a callback to reclaim memory if necessary. If memory cannot be
found the 'if (reclaim)' block is entered and the callback is called.
However, I would like to implement some kind of barrier that prevents the
callback from calling suba_alloc recusively. One recursive call is ok,
but if memory isn't found a second time, chances are good an infinate
loop will occur.
So how can I limit this recursive call? Below I have devised a method of
saving the address of an object on the first call reasoning that
subsiquent calls cannot reuse the same address but this is a poor
solution as it is difficult to reset the reclaim_barrier to NULL.
Does any else have a simple solution to limit this recursive call in the
way I've described?
void *
suba_alloc(struct allocator *suba, size_t size, int zero)
{
int reclaim = 0;
again:
if (reclaim) {
if (suba->reclaim_barrier == NULL) {
suba->reclaim_barrier = &reclaim;
}
if (suba->reclaim == NULL || suba->reclaim_barrier != &reclaim ||
suba->reclaim(suba, suba->reclaim_arg, reclaim) == 0) {
errno = ENOMEM;
return NULL;
}
}
if (can't find memory) {
reclaim++;
goto again;
}
return the memory;
}
Thanks,
Mike