]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/queue.cpp
update
[l4.git] / kernel / fiasco / src / kern / queue.cpp
1 INTERFACE:
2
3 #include "spin_lock.h"
4 #include "queue_item.h"
5 #include "kdb_ke.h"
6 #include <dlist>
7
8 class Queue
9 {
10 public:
11   typedef Spin_lock_coloc<Mword> Inner_lock;
12
13 private:
14   class Lock_n_ptr : public Inner_lock
15   {
16   public:
17     Queue_item *item() const
18     { return reinterpret_cast<Queue_item*>(get_unused() & ~5UL); }
19
20     void set_item(Queue_item *i)
21     {
22       assert_kdb (!(Mword(i) & 5));
23       set_unused((Mword)i | (get_unused() & 5));
24     }
25
26     bool blocked() const
27     { return get_unused() & 1; }
28
29     void block()
30     { return set_unused(get_unused() | 1); }
31
32     void unblock()
33     { set_unused(get_unused() & ~1); }
34
35     bool invalid() const
36     { return get_unused() & 4; }
37
38     void invalidate()
39     { set_unused(get_unused() | 4); }
40   };
41
42   struct Queue_head_policy
43   {
44     typedef Lock_n_ptr Head_type;
45     static Queue_item *head(Head_type const &h) { return h.item(); }
46     static void set_head(Head_type &h, Queue_item *v) { h.set_item(v); }
47   };
48
49   typedef cxx::Sd_list<Queue_item, cxx::D_list_item_policy, Queue_head_policy> List;
50
51   List _m;
52 };
53
54
55 //--------------------------------------------------------------------------
56 IMPLEMENTATION:
57
58 #include "kdb_ke.h"
59 #include "std_macros.h"
60
61 PUBLIC inline
62 Queue::Queue()
63 { _m.head().init(); }
64
65 PUBLIC inline
66 Queue::Inner_lock *
67 Queue::q_lock()
68 { return &_m.head(); }
69
70 PUBLIC inline NEEDS["kdb_ke.h"]
71 void
72 Queue::enqueue(Queue_item *i)
73 {
74   // Queue i at the end of the list
75   assert_kdb (_m.head().test());
76   i->_q = this;
77   _m.push_back(i);
78 }
79
80 PUBLIC inline NEEDS["kdb_ke.h", "std_macros.h"]
81 bool
82 Queue::dequeue(Queue_item *i, Queue_item::Status reason)
83 {
84   assert_kdb (_m.head().test());
85   assert_kdb (i->queued());
86
87   if (EXPECT_FALSE(i->_q != this))
88     return false;
89
90   _m.remove(i);
91   i->_q = (Queue*)reason;
92   return true;
93 }
94
95 PUBLIC inline
96 Queue_item *
97 Queue::first() const
98 { return _m.front(); }
99
100 PUBLIC inline
101 bool
102 Queue::blocked() const
103 { return _m.head().blocked(); }
104
105 PUBLIC inline NEEDS["kdb_ke.h"]
106 void
107 Queue::block()
108 {
109   assert_kdb (_m.head().test());
110   _m.head().block();
111 }
112
113 PUBLIC inline NEEDS["kdb_ke.h"]
114 void
115 Queue::unblock()
116 {
117   assert_kdb (_m.head().test());
118   _m.head().unblock();
119 }
120
121 PUBLIC inline NEEDS["kdb_ke.h"]
122 bool
123 Queue::invalid() const
124 {
125   assert_kdb (_m.head().test());
126   return _m.head().invalid();
127 }
128
129 PUBLIC inline NEEDS["kdb_ke.h"]
130 void
131 Queue::invalidate()
132 {
133   assert_kdb (_m.head().test());
134   _m.head().invalidate();
135 }
136