]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/boot_alloc.cpp
update
[l4.git] / kernel / fiasco / src / kern / boot_alloc.cpp
1 INTERFACE:
2
3 #include <cstddef>
4 #include <cxx/slist>
5 #include <cxx/type_traits>
6
7 class Boot_alloced
8 {
9 private:
10   struct Block : cxx::S_list_item
11   { size_t size; };
12
13   typedef cxx::S_list_bss<Block> Block_list;
14
15   static Block_list _free;
16 };
17
18 template< typename Base >
19 class Boot_object : public Base, public Boot_alloced
20 {
21 public:
22   Boot_object()  = default;
23
24   template< typename... A >
25   Boot_object(A&&... args) : Base(cxx::forward<A>(args)...) {}
26 };
27
28
29 IMPLEMENTATION:
30
31 #include <cstdio>
32
33 #include "kmem_alloc.h"
34 #include "warn.h"
35
36 Boot_alloced::Block_list Boot_alloced::_free;
37
38 PUBLIC static
39 void *
40 Boot_alloced::alloc(size_t size)
41 {
42   printf("Boot_alloc: size=0x%lx\n", (unsigned long)size);
43
44   // this is best fit list-based allocation
45
46   Block_list::Iterator best = _free.end();
47   for (Block_list::Iterator curr = _free.begin(); curr != _free.end(); ++curr)
48     {
49       if (((best == _free.end()) || curr->size < best->size)
50           && curr->size >= size)
51         best = curr;
52     }
53
54   if (best == _free.end())
55     {
56       // start from 1k
57       unsigned long alloc_size = 1024;
58
59       // look for a size suitable and buddy friendly
60       while (alloc_size < size)
61         alloc_size <<= 1;
62
63       Block *b = (Block*)Kmem_alloc::allocator()->unaligned_alloc(alloc_size);
64       printf("Boot_alloc: allocated extra memory block @%p (size=%lx)\n",
65              b, alloc_size);
66
67       if (!b)
68         return 0;
69
70       b->size = alloc_size;
71       _free.add(b);
72       best = _free.begin();
73     }
74
75
76   void *b = *best;
77   Block *rem = (Block *)(((Address)b + size + sizeof(Block) - 1) & ~(sizeof(Block) - 1));
78   long rem_sz = (Address)b + (*best)->size - (Address)rem;
79   printf("Boot_alloc: @ %p\n", b);
80   if (rem_sz > (long)sizeof(Block))
81     {
82       rem->size = rem_sz;
83       _free.replace(best, rem);
84       printf("Boot_alloc: remaining free block @ %p (size=%lx)\n", rem, rem_sz);
85     }
86   else
87     _free.erase(best);
88   return b;
89 }
90
91 PUBLIC inline void *
92 Boot_alloced::operator new (size_t size) throw()
93 { return alloc(size); }
94
95 PUBLIC inline void *
96 Boot_alloced::operator new [] (size_t size) throw()
97 { return alloc(size); }
98
99 PUBLIC void
100 Boot_alloced::operator delete (void *b)
101 {
102   WARN("Boot_alloc: trying to delete boot-time allocated object @ %p\n", b);
103 }
104
105 PUBLIC void
106 Boot_alloced::operator delete [] (void *b)
107 {
108   WARN("Boot_alloc: trying to delete boot-time allocated object @ %p\n", b);
109 }
110