]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kobject.cpp
update
[l4.git] / kernel / fiasco / src / kern / kobject.cpp
1 INTERFACE:
2
3 #include "lock.h"
4 #include "obj_space.h"
5
6
7 class Kobject_mappable
8 {
9 private:
10   friend class Kobject_mapdb;
11   friend class Jdb_mapdb;
12   Obj::Mapping *_root;
13   Smword _cnt;
14   Lock _lock;
15
16 public:
17   Kobject_mappable() : _root(0), _cnt(0) {}
18   bool no_mappings() const { return !_root; }
19
20   /**
21    * Insert the root mapping of an object.
22    */
23   template<typename M>
24   bool insert(void *, Space *, M &m)
25   {
26     m._c->put_as_root(&_root);
27     _cnt = 1;
28     return true;
29   }
30
31   Smword cap_ref_cnt() const { return _cnt; }
32 };
33
34
35 //----------------------------------------------------------------------------
36 INTERFACE:
37
38 #include "context.h"
39 #include "irq_pin.h"
40 #include "kobject_dbg.h"
41 #include "kobject_iface.h"
42 #include "l4_error.h"
43 #include "rcupdate.h"
44 #include "space.h"
45
46 class Kobject :
47   public virtual Kobject_common,
48   private Kobject_mappable,
49   public Kobject_dbg
50 {
51   template<typename T>
52   friend class Map_traits;
53
54 public:
55   Kobject_mappable *map_root() { return this; }
56   Kobject_dbg *dbg_info() { return this; }
57   Kobject_dbg const *dbg_info() const { return this; }
58   Kobject *kobject() { return this; }
59   Kobject const *kobject() const { return this; }
60
61 private:
62   template<typename T>
63   class Tconv {};
64
65   template<typename T>
66   class Tconv<T*> { public: typedef T Base; };
67
68 public:
69   bool is_local(Space *) const { return false; }
70   Mword obj_id() const { return ~0UL; }
71   void initiate_deletion(Kobject ***);
72   void destroy(Kobject ***);
73   bool put() { return true; }
74
75   template<typename T>
76   static T dcast(Kobject_common *_o)
77   {
78     if (EXPECT_FALSE(!_o))
79       return 0;
80
81     if (EXPECT_TRUE(_o->kobj_type() == Tconv<T>::Base::static_kobj_type))
82       return reinterpret_cast<T>(_o->kobject_start_addr());
83     return 0;
84   }
85
86   template<typename T>
87   static T dcast(Kobject_common const *_o)
88   {
89     if (EXPECT_FALSE(!_o))
90       return 0;
91
92     if (EXPECT_TRUE(_o->kobj_type() == Tconv<T>::Base::static_kobj_type))
93       return reinterpret_cast<T>(_o->kobject_start_addr());
94     return 0;
95   }
96
97   Lock existence_lock;
98
99 public:
100   Kobject *_next_to_reap;
101
102 public:
103   enum Op {
104     O_dec_refcnt = 0,
105   };
106
107 };
108
109 #define FIASCO_DECLARE_KOBJ() \
110   public: static char const *const static_kobj_type; \
111           char const *kobj_type() const { return static_kobj_type; } \
112           Address kobject_start_addr() const { return (Address)this; } \
113           Mword kobject_size() const { return sizeof(*this); }
114
115 #define FIASCO_DEFINE_KOBJ(t) \
116   char const *const t::static_kobj_type = #t
117
118
119 //---------------------------------------------------------------------------
120 IMPLEMENTATION:
121
122 #include "logdefs.h"
123 #include "l4_buf_iter.h"
124 #include "lock_guard.h"
125
126 PUBLIC inline NEEDS["lock_guard.h"]
127 Smword
128 Kobject_mappable::dec_cap_refcnt(Smword diff)
129 {
130   Lock_guard<Lock> g(&_lock);
131   _cnt -= diff;
132   return _cnt;
133 }
134
135
136 IMPLEMENT inline
137 void
138 Kobject::initiate_deletion(Kobject ***reap_list)
139 {
140   existence_lock.invalidate();
141
142   _next_to_reap = 0;
143   **reap_list = this;
144   *reap_list = &_next_to_reap;
145 }
146
147 IMPLEMENT
148 void
149 Kobject::destroy(Kobject ***)
150 {
151   LOG_TRACE("Kobject destroy", "des", current(), __fmt_kobj_destroy,
152       Log_destroy *l = tbe->payload<Log_destroy>();
153       l->id = dbg_id();
154       l->obj = this;
155       l->type = kobj_type());
156   existence_lock.wait_free();
157 }
158
159 PUBLIC virtual
160 Kobject::~Kobject()
161 {
162   LOG_TRACE("Kobject delete (generic)", "del", current(), __fmt_kobj_destroy,
163       Log_destroy *l = tbe->payload<Log_destroy>();
164       l->id = dbg_id();
165       l->obj = this;
166       l->type = "unk");
167 }
168
169
170 PRIVATE inline NOEXPORT
171 L4_msg_tag
172 Kobject::sys_dec_refcnt(L4_msg_tag tag, Utcb const *in, Utcb *out)
173 {
174   if (tag.words() < 2)
175     return Kobject_iface::commit_result(-L4_err::EInval);
176
177   Smword diff = in->values[1];
178   out->values[0] = dec_cap_refcnt(diff);
179   return Kobject_iface::commit_result(0);
180 }
181
182 PUBLIC
183 L4_msg_tag
184 Kobject::kobject_invoke(L4_obj_ref, Mword /*rights*/,
185                         Syscall_frame *f,
186                         Utcb const *in, Utcb *out)
187 {
188   L4_msg_tag tag = f->tag();
189
190   if (EXPECT_FALSE(tag.words() < 1))
191     return Kobject_iface::commit_result(-L4_err::EInval);
192
193   switch (in->values[0])
194     {
195     case O_dec_refcnt:
196       return sys_dec_refcnt(tag, in, out);
197     default:
198       return Kobject_iface::commit_result(-L4_err::ENosys);
199     }
200
201 }
202
203 PUBLIC static
204 Kobject *
205 Kobject::id_to_obj(unsigned long id)
206 { return static_cast<Kobject*>(Kobject_dbg::id_to_obj(id)); }
207
208 PUBLIC static inline
209 Kobject *
210 Kobject::pointer_to_obj(void const *p)
211 { return static_cast<Kobject*>(Kobject_dbg::pointer_to_obj(p)); }
212
213
214 //---------------------------------------------------------------------------
215 INTERFACE [debug]:
216
217 #include "tb_entry.h"
218
219 EXTENSION class Kobject
220 {
221 protected:
222   struct Log_destroy
223   {
224     Kobject    *obj;
225     Mword       id;
226     char const *type;
227     Mword       ram;
228   };
229
230   static unsigned log_fmt(Tb_entry *, int max, char *buf) asm ("__fmt_kobj_destroy");
231 };
232
233 //---------------------------------------------------------------------------
234 IMPLEMENTATION [debug]:
235
236
237 IMPLEMENT
238 unsigned
239 Kobject::log_fmt(Tb_entry *e, int max, char *buf)
240 {
241   Log_destroy *l = e->payload<Log_destroy>();
242   return snprintf(buf, max, "obj=%lx [%s] (%p) ram=%lx", l->id, l->type, l->obj, l->ram);
243 }