2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
10 #include <l4/cxx/exceptions>
11 #include <l4/cxx/auto_ptr>
12 #include <l4/cxx/l4iostream>
14 #include <l4/re/protocols>
15 #include <l4/re/mem_alloc-sys.h>
16 #include <l4/re/mem_alloc>
17 #include <l4/re/util/meta>
18 #include <l4/sys/factory>
23 #include "dataspace_annon.h"
24 #include "dataspace_noncont.h"
26 #include "page_alloc.h"
27 #include "slab_alloc.h"
30 #include "name_space.h"
32 #include "sched_proxy.h"
34 typedef Moe::Q_alloc<Allocator, Slab_alloc> Alloc;
36 template< typename C >
37 class Quota_obj : public C
40 typedef Moe::Q_alloc<Quota_obj<C>, Slab_alloc> Alloc;
41 static Alloc *_allocator()
48 virtual ~Quota_obj() {}
49 void *operator new (size_t size, Moe::Quota *q)
51 if (size != sizeof(Quota_obj))
52 throw L4::Out_of_memory();
54 return _allocator()->alloc(q);
57 void operator delete(void *o)
59 _allocator()->free((Quota_obj*)o);
64 template< typename A1 >
65 Quota_obj(A1 a1) : C(a1) {}
67 template< typename A1, typename A2 >
68 Quota_obj(A1 a1, A2 a2) : C(a1, a2) {}
70 template< typename A1, typename A2, typename A3 >
71 Quota_obj(A1 a1, A2 a2, A3 a3) : C(a1, a2, a3) {}
82 void *Allocator::operator new (size_t, Moe::Quota *q, size_t limit)
84 return slab()->alloc(q, limit);
87 void Allocator::operator delete (void *m) throw()
89 slab()->free((Allocator*)m);
93 Allocator::alloc(unsigned long size, unsigned long flags)
96 throw L4::Bounds_error("stack too small");
98 //L4::cout << "A: \n";
100 if (flags & L4Re::Mem_alloc::Continuous
101 || flags & L4Re::Mem_alloc::Pinned)
102 mo = new (&_quota) Moe::Dataspace_annon(size, true,
103 flags & L4Re::Mem_alloc::Super_pages
104 ? L4_SUPERPAGESHIFT : L4_PAGESHIFT);
106 mo = Moe::Dataspace_noncont::create(&_quota, size);
108 // L4::cout << "A: mo=" << mo << "\n";
110 //L4::cout << "A[" << this << "]: allocated(" << mo << " " << mo->obj_cap() << ")\n";
114 Allocator::~Allocator()
116 if (Q_object::quota())
117 Q_object::quota()->free(_quota.limit());
121 Allocator::open(int, cxx::String const *argv)
123 unsigned long sz = strtol(argv[0].start(), 0, 0);
126 //L4::cerr << "could not parse quota value!\n";
129 Allocator *child = new (&_quota, sz) Allocator(sz);
130 object_pool.cap_alloc()->alloc(child);
135 class LLog : public Moe::Log
141 LLog(char const *t, int l, unsigned char col) : Log()
157 Allocator::disp_factory(l4_umword_t r, L4::Ipc::Iostream &ios)
159 if (!(r & L4_CAP_FPAGE_S))
162 L4::Factory::Proto o;
165 L4::Cap<L4::Kobject> ko;
169 case L4Re::Protocol::Namespace:
170 ko = object_pool.cap_alloc()->alloc(new (&_quota) Quota_obj<Moe::Name_space>());
175 case L4Re::Protocol::Rm:
176 ko = object_pool.cap_alloc()->alloc(new (&_quota) Quota_obj<Region_map>());
181 case L4::Factory::Protocol:
182 case L4Re::Protocol::Mem_alloc:
187 if (!tag.is_of_int()) // ignore sign
189 Allocator *child = new (&_quota, tag.value<long>()) Allocator(tag.value<long>());
190 ko = object_pool.cap_alloc()->alloc(child);
202 if (!tag.is_of<char const *>())
209 if (col.is_of<char const *>())
210 color = LLog::color_value(cxx::String(col.value<char const*>(),
212 else if(col.is_of_int())
213 color = col.value<l4_mword_t>();
217 Moe::Log *l = new (&_quota) Quota_obj<LLog>(tag.value<char const*>(), tag.length(), color);
218 ko = object_pool.cap_alloc()->alloc(l);
225 case L4::Scheduler::Protocol:
227 if (!_sched_prio_limit)
230 L4::Ipc::Varg p_max, p_base, cpus;
235 if (!p_max.is_of_int() || !p_base.is_of_int())
238 if (p_max.value<l4_mword_t>() > _sched_prio_limit
239 || p_base.value<l4_mword_t>() > _sched_prio_limit)
242 if (p_max.value<l4_mword_t>() <= p_base.value<l4_mword_t>())
245 l4_umword_t cpu_mask = ~0UL;
247 if (!cpus.is_of<void>() && cpus.is_of_int())
248 cpu_mask = cpus.value<l4_umword_t>();
250 Sched_proxy *o = new (&_quota) Quota_obj<Sched_proxy>();
251 o->set_prio(p_base.value<l4_mword_t>(), p_max.value<l4_mword_t>());
252 o->restrict_cpus(cpu_mask);
253 ko = object_pool.cap_alloc()->alloc(o);
259 case L4Re::Dataspace::Protocol:
261 L4::Ipc::Varg size, flags;
262 ios >> size >> flags;
264 if (!size.is_of_int())
267 // L4::cout << "MEM: alloc ... " << size.value<l4_umword_t>() << "; " << flags.value<l4_umword_t>() << "\n";
268 cxx::Auto_ptr<Moe::Dataspace> mo(alloc(size.value<l4_umword_t>(),
269 flags.is_of_int() ? flags.value<l4_umword_t>() : 0));
271 // L4::cout << "MO=" << mo.get() << "\n";
272 ko = object_pool.cap_alloc()->alloc(mo.get());
274 // L4::cout << "MO_CAP=" << mo->obj_cap() << "\n";
285 // create out annonymous combination of a memory allocctaor and a factory
286 class Moe_allocator :
287 public L4::Kobject_2t<Moe_allocator, L4::Factory, L4Re::Mem_alloc>
291 Allocator::dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios)
299 case L4::Meta::Protocol:
300 return L4Re::Util::handle_meta_request<Moe_allocator>(ios);
301 case L4::Factory::Protocol:
302 return disp_factory(obj, ios);
304 case L4Re::Protocol::Mem_alloc:
309 case L4Re::Mem_alloc_::Alloc:
313 ios >> size >> flags;
315 //L4::cout << "MEM: alloc ... " << size << "; " << flags << "\n";
316 cxx::Auto_ptr<Moe::Dataspace> mo(alloc(size,flags));
318 // L4::cout << "MO=" << mo.get() << "\n";
319 L4::Cap<void> o = object_pool.cap_alloc()->alloc(mo.get());
320 //L4::cout << "MO_CAP=" << mo->obj_cap() << "\n";
325 case L4Re::Mem_alloc_::Free:
327 l4_umword_t rc1, rc2;
329 Moe::Dataspace *mo = 0;
331 if ((rc1 & 0xe) == 0xc) // XXX: change with cap.id_received()
332 mo = dynamic_cast<Moe::Dataspace*>(object_pool.find(rc2));
335 // FIXME: check if dataspace comes from this allocator
337 if (!mo || mo->is_static())
340 object_pool.cap_alloc()->free(mo);
349 case L4Re::Protocol::Debug:
351 printf("MOE: mem_alloc: quota: limit=%zd Byte, used=%zd Byte\n",
352 _quota.limit(), _quota.used());
353 printf("MOE: mem_alloc: global: avail=%ld Byte\n",
354 Single_page_alloc_base::_avail());
358 return -L4_EBADPROTO;
364 Allocator::root_allocator()
366 static Allocator ra(~0, 300000);