3 * Fixed-size Objects Memory Allocator
5 * Copyright (C) 2008-2009 Pawel Dziepak
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 /* Propably this implementation is LE only */
28 #include "arch/low/fast_util.h"
29 #include "services/kernel_state.h"
30 #include "manes/manec.h"
34 using namespace manes
;
35 using namespace resources
;
37 bool foma::initialize() {
41 physical
= manec::get()->get
<physmem
>("/physmem");
42 memory_size
= manec::get()->state()->get_memory_size();
44 start_heap
= (void*)0x300000;
45 for (int i
= 0; i
< 20; i
++)
49 void *foma::get_page(int size
) {
50 void *addr
= physical
->allocate_space(0x1000);
52 *(unsigned int*)addr
= 1 << size
;
59 void *foma::allocate(unsigned int fixed_size
, unsigned int size
) {
60 unsigned int index
= log2up(fixed_size
);
62 assert("foma: attempt to allocate too big object", index
> PAGE_SHIFT
);
64 if (first_block
[index
] == 0) {
65 first_block
[index
] = (unsigned int*)((unsigned int)get_page(index
) + (1 << index
));
69 for (; i
< PAGE_SIZE
- fixed_size
; i
+= fixed_size
) {
70 *(unsigned int*)((unsigned int)first_block
[index
] + i
) = (unsigned int)first_block
[index
] + i
+ fixed_size
;
72 *(unsigned int*)((unsigned int)first_block
[index
] + i
- fixed_size
) = 0;
74 alloc_memory
+= fixed_size
;
78 unsigned int *next_block
= (unsigned int*)*first_block
[index
];
79 unsigned int *found_block
= first_block
[index
];
81 first_block
[index
] = next_block
;
83 return (void*)found_block
;
86 void foma::deallocate(void *ptr
, unsigned int size
) {
87 unsigned int index
= log2up(size
);
88 unsigned int fixed_size
= 1 << index
;
93 assert("foma: attempt to deallocate too big object", index
> PAGE_SHIFT
);
94 if (index
> PAGE_SHIFT
)
97 unsigned int next_block
= (unsigned int)first_block
[index
];
98 unsigned int *new_first_block
= (unsigned int*)ptr
;
100 first_block
[index
] = new_first_block
;
101 *new_first_block
= next_block
;
104 //#if DEBUG_MODE == CONF_YES
105 int resources::foma::used_memory
= 0;
108 void *foma::allocate_space(unsigned int size
) {
112 if (size
< PAGE_SIZE
) {
113 unsigned int fixed_size
= 1 << log2up(size
< sizeof(void*) ? sizeof(void*) : size
);
114 #if DEBUG_MODE == CONF_YES
116 alloc_memory
+= fixed_size
;
118 return allocate(fixed_size
< sizeof(void*) ? sizeof(void*) : fixed_size
, size
);
120 void *first_page
= get_page(PAGE_SHIFT
+ 1);
121 for (int i
= size
- PAGE_SIZE
; i
> 0; i
-= PAGE_SIZE
)
122 get_page(PAGE_SHIFT
+ 1);
128 void foma::deallocate_space(void *ptr
) {
129 assert("foma: attempt to free null pointer", ptr
== 0);
130 if ((unsigned int)ptr
< 0x300000 || (unsigned int)ptr
>= 0x400000) {
131 assert((string
)"foma: attempt to free object not created by foma: 0x" + string((int)ptr
,true),1);
135 unsigned int size
= get_size(ptr
);
137 if (size
< PAGE_SIZE
) {
138 deallocate(ptr
, size
);
140 debug("foma: deallocating object larger than page");
144 unsigned int foma::get_size(void *ptr
) const {
145 return *(unsigned int*)((unsigned int)ptr
& ~(PAGE_SIZE
- 1));
148 void foma::register_type() {
149 manec::get()->register_type
<foma
>("foma", "allocator");