net: tcp_client_socket connection state routines
[quarnos.git] / resources / foma.cpp
blobdfbb8bd224733c482054aff592b1cae8a7c1ef0f
1 /* Quarn OS
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 */
25 #include "foma.h"
26 #include "memm.h"
28 #include "arch/low/fast_util.h"
29 #include "services/kernel_state.h"
30 #include "manes/manec.h"
31 #include "physmem.h"
33 using namespace arch;
34 using namespace manes;
35 using namespace resources;
37 bool foma::initialize() {
40 foma::foma() {
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++)
46 first_block[i] = 0;
49 void *foma::get_page(int size) {
50 void *addr = physical->allocate_space(0x1000);
52 *(unsigned int*)addr = 1 << size;
54 return addr;
57 int alloc_memory = 0;
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));
67 unsigned int i = 0;
68 /* O(1) !!! */
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;
77 /* Allocate object */
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;
90 if (fixed_size < 4)
91 return;
93 assert("foma: attempt to deallocate too big object", index > PAGE_SHIFT);
94 if (index > PAGE_SHIFT)
95 return;
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;
106 //#endif
108 void *foma::allocate_space(unsigned int size) {
109 if (size == 0)
110 return (void*)0;
112 if (size < PAGE_SIZE) {
113 unsigned int fixed_size = 1 << log2up(size < sizeof(void*) ? sizeof(void*) : size);
114 #if DEBUG_MODE == CONF_YES
115 used_memory += size;
116 alloc_memory += fixed_size;
117 #endif
118 return allocate(fixed_size < sizeof(void*) ? sizeof(void*) : fixed_size, size);
119 } else {
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);
124 return first_page;
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);
132 return;
135 unsigned int size = get_size(ptr);
137 if (size < PAGE_SIZE) {
138 deallocate(ptr, size);
139 } else {
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");