]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/mapped_alloc.cpp
update
[l4.git] / kernel / fiasco / src / kern / mapped_alloc.cpp
1 INTERFACE:
2
3 #include <cstddef> // size_t
4 #include "types.h"
5
6 class Mapped_allocator
7 {
8 public:
9   /// allocate s bytes size-aligned
10   virtual void *alloc(size_t order) = 0;
11
12   /// free s bytes previously allocated with alloc(s)
13   virtual void free(size_t order, void *p) = 0;
14
15   virtual void *unaligned_alloc(unsigned long size) = 0;
16   virtual void unaligned_free(unsigned long size, void *p) = 0;
17
18   virtual void dump() const {}
19 private:
20   static Mapped_allocator *_alloc;
21 };
22
23 class Mapped_alloc_reaper
24 {
25   size_t (*_reap)(bool desperate);
26   Mapped_alloc_reaper* _next;
27
28 private:
29   static Mapped_alloc_reaper* mem_reapers;
30 };
31
32
33 IMPLEMENTATION:
34
35 #include <cassert>
36
37 #include "mem_layout.h"
38
39 // 
40 // class Mapped_allocator
41 // 
42
43 Mapped_allocator* Mapped_allocator::_alloc;
44
45 PUBLIC static
46 Mapped_allocator *
47 Mapped_allocator::allocator()
48 {
49   assert (_alloc /* uninitialized use of Mapped_allocator */);
50   return _alloc;
51 }
52
53 PROTECTED static
54 void
55 Mapped_allocator::allocator(Mapped_allocator *a)
56 {
57   _alloc=a;
58 }
59
60 PUBLIC inline NEEDS["mem_layout.h"]
61 void Mapped_allocator::free_phys(size_t s, Address p)
62 {
63   void *va = (void*)Mem_layout::phys_to_pmem(p);
64   if((unsigned long)va != ~0UL)
65     free(s, va);
66 }
67
68 PUBLIC template< typename Q >
69 inline
70 void *
71 Mapped_allocator::q_alloc(Q *quota, size_t order)
72 {
73   if (EXPECT_FALSE(!quota->alloc(1UL<<order)))
74     return 0;
75
76   void *b;
77   if (EXPECT_FALSE(!(b=alloc(order))))
78     {
79       quota->free(1UL<<order);
80       return 0;
81     }
82
83   return b;
84 }
85
86 PUBLIC template< typename Q >
87 inline
88 void *
89 Mapped_allocator::q_unaligned_alloc(Q *quota, size_t size)
90 {
91   if (EXPECT_FALSE(!quota->alloc(size)))
92     return 0;
93
94   void *b;
95   if (EXPECT_FALSE(!(b=unaligned_alloc(size))))
96     {
97       quota->free(size);
98       return 0;
99     }
100
101   return b;
102 }
103
104 PUBLIC template< typename Q >
105 inline
106 void 
107 Mapped_allocator::q_free_phys(Q *quota, size_t order, Address obj)
108 {
109   free_phys(order, obj);
110   quota->free(1UL<<order);
111 }
112
113 PUBLIC template< typename Q >
114 inline
115 void 
116 Mapped_allocator::q_free(Q *quota, size_t order, void *obj)
117 {
118   free(order, obj);
119   quota->free(1UL<<order);
120 }
121
122 PUBLIC template< typename Q >
123 inline
124 void 
125 Mapped_allocator::q_unaligned_free(Q *quota, size_t size, void *obj)
126 {
127   unaligned_free(size, obj);
128   quota->free(size);
129 }
130
131 // 
132 // class Mapped_alloc_reaper
133 // 
134
135 #include "atomic.h"
136 #include "warn.h"
137
138 Mapped_alloc_reaper* Mapped_alloc_reaper::mem_reapers;
139
140 PUBLIC inline NEEDS["atomic.h"]
141 Mapped_alloc_reaper::Mapped_alloc_reaper (size_t (*reap)(bool desperate))
142   : _reap (reap)
143 {
144   do {
145     _next = mem_reapers;
146   } while (! cas (&mem_reapers, _next, this));
147 }
148
149 PUBLIC static
150 size_t
151 Mapped_alloc_reaper::morecore (bool desperate = false)
152 {
153   size_t freed = 0;
154
155   for (Mapped_alloc_reaper* reaper = mem_reapers;
156        reaper;
157        reaper = reaper->_next)
158     {
159       freed += reaper->_reap(desperate);
160     }
161 #if 0
162   if (desperate)
163     WARN ("morecore freed %lu bytes of memory\n",
164           static_cast<unsigned long>(freed));
165 #endif
166
167   return freed;
168 }