]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/moe/server/src/obj_reg.h
Update
[l4.git] / l4 / pkg / l4re-core / moe / server / src / obj_reg.h
1 /*
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)
5  *
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.
9  */
10 #pragma once
11
12 #include <l4/sys/task.h>
13 #include <l4/sys/factory.h>
14 #include <l4/sys/types.h>
15 #include <l4/sys/thread>
16
17 #include <l4/re/util/bitmap_cap_alloc>
18 #include <l4/re/error_helper>
19 #include <l4/re/env>
20
21 #include <l4/cxx/exceptions>
22 #include <l4/cxx/hlist>
23
24 #include "server_obj.h"
25
26 #include <cstring>
27 #include <cassert>
28 #include <cstdio>
29
30 #define DEBUG_CAP_ALLOC 0
31
32 enum
33 {
34   Rcv_cap = 0x100,
35 };
36
37 class Cap_alloc;
38
39 class Object_pool
40 : public L4::Basic_registry,
41   private L4::Irqep_t<Object_pool>
42 {
43   friend struct L4::Irqep_t<Object_pool>;
44
45 public:
46   explicit Object_pool(Cap_alloc *ca);
47   Cap_alloc *cap_alloc() const { return _cap_alloc; }
48   cxx::H_list_t<Moe::Server_object> life;
49
50 private:
51   Cap_alloc *_cap_alloc;
52
53   void handle_irq()
54   {
55     l4_utcb_t *utcb = l4_utcb();
56     for (auto i = life.begin(); i != life.end();)
57       {
58         if (i->obj_cap() && !i->obj_cap().validate(utcb).label())
59           delete *i;
60         else
61           ++i;
62       }
63   }
64 };
65
66 class Cap_alloc
67 {
68 public:
69   enum
70   {
71     Non_gc_caps = 8192,
72     Non_gc_cap_0 = Rcv_cap + 1,
73   };
74
75 private:
76   // caps mainly used for things from outside (registered in name spaces)
77   // this are usually not a lot
78   L4Re::Util::Cap_alloc<Non_gc_caps> _non_gc;
79
80 public:
81   Cap_alloc() : _non_gc(Non_gc_cap_0)
82   {}
83
84   L4::Cap<L4::Kobject> alloc()
85   {
86      L4::Cap<L4::Kobject> cap = _non_gc.alloc<L4::Kobject>();
87 #if DEBUG_CAP_ALLOC
88      L4::cerr << "AC->" << L4::n_hex(cap.cap()) << "\n";
89 #endif
90      return cap;
91   }
92
93   template< typename T >
94   L4::Cap<T> alloc() { return L4::cap_cast<T>(alloc()); }
95
96   L4::Cap<L4::Kobject> alloc(Moe::Server_object *_o)
97   {
98     // make sure we register an Epiface ptr
99     L4::Epiface *o = _o;
100     L4::Cap<L4::Kobject> cap = _non_gc.alloc<L4::Kobject>();
101 #if  DEBUG_CAP_ALLOC
102     L4::cerr << "ACO->" << L4::n_hex(cap.cap()) << "\n";
103 #endif
104     if (!cap.is_valid())
105       throw(L4::Out_of_memory());
106
107     l4_umword_t id = l4_umword_t(o);
108     l4_factory_create_gate(L4_BASE_FACTORY_CAP, cap.cap(),
109                            L4_BASE_THREAD_CAP, id);
110
111     _o->set_obj_cap(cap);
112     return cap;
113   }
114
115   bool free(L4::Cap<void> const &cap, l4_umword_t unmap_flags = L4_FP_ALL_SPACES)
116   {
117     if (!cap.is_valid())
118       return false;
119
120     if ((cap.cap() >> L4_CAP_SHIFT) >= Non_gc_cap_0)
121       _non_gc.free(cap, L4_BASE_TASK_CAP, unmap_flags);
122     else
123       return false;
124
125     return true;
126   }
127
128 };
129
130 inline Object_pool::Object_pool(Cap_alloc *ca) : _cap_alloc(ca)
131 {
132   // make sure we register an Epiface PTR
133   L4::Epiface *self = this;
134   auto c = L4Re::chkcap(cap_alloc()->alloc<L4::Irq>());
135   L4Re::chksys(L4Re::Env::env()->factory()->create(c));
136   L4Re::chksys(c->attach(l4_umword_t(self),
137                          L4::Cap<L4::Thread>(L4_BASE_THREAD_CAP)));
138   set_obj_cap(c);
139   L4Re::chksys(L4::Cap<L4::Thread>(L4_BASE_THREAD_CAP)->register_del_irq(c));
140 }
141