1 /* Simple List of Blocks allocator
2 * Based on the SLOB allocator introduced to Linux kernel by M. Mackall.
4 * M. Mackall: slob: introduce the SLOB allocator, Linux Kernel Mailing List,
5 * 2005, http://lkml.org/lkml/2005/11/1/230
9 #include "manes/manec.h"
11 using namespace resources
;
14 physical
= manes::manec::get()->get
<physmem
>("/physmem");
15 first_block
= (unit
*)physical
->allocate_space(0x1000);
16 first_block
->size
= 0x1000;
17 first_block
->next
= (unit
*)0;
20 void *slob::allocate_space(unsigned int size
) {
22 unit
*current
= first_block
;
24 if (size
< sizeof(unit
))
28 size
= (size
/ sizeof(unit
) + 1) * sizeof(unit
);
31 void *first_page
= physical
->allocate_space(PAGE_SHIFT
+ 1);
32 for (int i
= size
- PAGE_SIZE
; i
> 0; i
-= PAGE_SIZE
)
33 physical
->allocate_space(PAGE_SHIFT
+ 1);
37 while (current
->size
< size
) {
39 current
->next
= (unit
*)physical
->allocate_space(0x1000);
40 current
->next
->size
= 0x1000;
41 current
->next
->next
= (unit
*)0;
45 current
= current
->next
;
50 if (current
->size
> size
) {
51 new_unit
= (unit
*)((int)current
+ size
);
53 new_unit
->size
= current
->size
- size
;
54 new_unit
->next
= current
->next
;
57 new_unit
= current
->next
;
60 before
->next
= new_unit
;
62 first_block
= new_unit
;
67 return (void*)¤t
[1];
70 void slob::deallocate_space(void *ptr
) {
71 if (((unsigned int)ptr
& 0xffff) == 0)
74 unit
*dealloc
= (unit
*)((int)ptr
- sizeof(unit
));
76 if (!merge(dealloc
)) {
77 dealloc
->next
= first_block
;
78 first_block
= dealloc
;
82 unsigned int slob::get_size(void *ptr
) const {
83 unit
*dealloc
= (unit
*)((int)ptr
- sizeof(unit
));
88 bool slob::merge(unit
*ptr
) {
89 unit
*current
= first_block
;
90 unit
*before
= (unit
*)0;
95 if ((unsigned int)current
+ current
->size
== (unsigned int)ptr
) {
96 current
->size
+= ptr
->size
;
101 } else if ((unsigned int)ptr
+ ptr
->size
== (unsigned int)current
) {
103 ptr
->next
= current
->next
;
104 ptr
->size
+= current
->size
;
114 current
= current
->next
;
121 void slob::register_type() {
122 manes::manec::get()->register_type
<slob
>("slob", "allocator");