mirror of
https://github.com/schoebel/mars
synced 2025-03-02 11:30:37 +00:00
infra: reduce memory fragmentation on aspect allocation
This commit is contained in:
parent
4b94866c80
commit
0dfd2deda7
18
brick.c
18
brick.c
@ -384,8 +384,11 @@ struct generic_object *generic_alloc(struct generic_brick *brick, struct generic
|
|||||||
aspect_nr_max = nr_max;
|
aspect_nr_max = nr_max;
|
||||||
total_size = object_size + aspect_nr_max * sizeof(void*);
|
total_size = object_size + aspect_nr_max * sizeof(void*);
|
||||||
hint_size = object_layout->size_hint;
|
hint_size = object_layout->size_hint;
|
||||||
if (likely(total_size < hint_size))
|
if (likely(total_size <= hint_size)) {
|
||||||
total_size = hint_size;
|
total_size = hint_size;
|
||||||
|
} else { // usually happens only at the first time
|
||||||
|
object_layout->size_hint = total_size;
|
||||||
|
}
|
||||||
|
|
||||||
data = brick_zmem_alloc(total_size);
|
data = brick_zmem_alloc(total_size);
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -473,10 +476,19 @@ struct generic_aspect *_new_aspect(struct generic_brick *brick, struct generic_o
|
|||||||
size = aspect_type->aspect_size;
|
size = aspect_type->aspect_size;
|
||||||
rest = obj->max_offset - obj->free_offset;
|
rest = obj->max_offset - obj->free_offset;
|
||||||
if (likely(size <= rest)) {
|
if (likely(size <= rest)) {
|
||||||
|
/* Optimisation: re-use single memory allocation for both
|
||||||
|
* the object and the new aspect.
|
||||||
|
*/
|
||||||
res = ((void*)obj) + obj->free_offset;
|
res = ((void*)obj) + obj->free_offset;
|
||||||
obj->free_offset += size;
|
obj->free_offset += size;
|
||||||
res->shortcut = true;
|
res->shortcut = true;
|
||||||
} else {
|
} else {
|
||||||
|
/* Maintain the size hint.
|
||||||
|
* In future, only small aspects should be integrated into
|
||||||
|
* the same memory block, and the hint should not grow larger
|
||||||
|
* than PAGE_SIZE if it was smaller before.
|
||||||
|
*/
|
||||||
|
if (size < PAGE_SIZE / 2) {
|
||||||
struct generic_object_layout *object_layout = obj->object_layout;
|
struct generic_object_layout *object_layout = obj->object_layout;
|
||||||
int max;
|
int max;
|
||||||
|
|
||||||
@ -485,8 +497,10 @@ struct generic_aspect *_new_aspect(struct generic_brick *brick, struct generic_o
|
|||||||
/* This is racy, but races won't do any harm because
|
/* This is racy, but races won't do any harm because
|
||||||
* it is just a hint, not essential.
|
* it is just a hint, not essential.
|
||||||
*/
|
*/
|
||||||
if (object_layout->size_hint < max)
|
if ((max < PAGE_SIZE || object_layout->size_hint > PAGE_SIZE) &&
|
||||||
|
object_layout->size_hint < max)
|
||||||
object_layout->size_hint = max;
|
object_layout->size_hint = max;
|
||||||
|
}
|
||||||
|
|
||||||
res = brick_zmem_alloc(size);
|
res = brick_zmem_alloc(size);
|
||||||
if (unlikely(!res)) {
|
if (unlikely(!res)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user