]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/queue.cpp
36559d26a8cc7896f74edc60bcc2af1e6d82fe13
[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 (i && !i->queued());
76   assert_kdb (_m.head().test());
77   i->_q = this;
78   _m.push_back(i);
79 }
80
81 PUBLIC inline NEEDS["kdb_ke.h", "std_macros.h"]
82 bool
83 Queue::dequeue(Queue_item *i, Queue_item::Status reason)
84 {
85   assert_kdb (_m.head().test());
86   assert_kdb (i->queued());
87
88   if (EXPECT_FALSE(i->_q != this))
89     return false;
90
91   _m.remove(i);
92   i->_q = (Queue*)reason;
93   return true;
94 }
95
96 PUBLIC inline
97 Queue_item *
98 Queue::first() const
99 { return _m.front(); }
100
101 PUBLIC inline
102 bool
103 Queue::blocked() const
104 { return _m.head().blocked(); }
105
106 PUBLIC inline NEEDS["kdb_ke.h"]
107 void
108 Queue::block()
109 {
110   assert_kdb (_m.head().test());
111   _m.head().block();
112 }
113
114 PUBLIC inline NEEDS["kdb_ke.h"]
115 void
116 Queue::unblock()
117 {
118   assert_kdb (_m.head().test());
119   _m.head().unblock();
120 }
121
122 PUBLIC inline NEEDS["kdb_ke.h"]
123 bool
124 Queue::invalid() const
125 {
126   assert_kdb (_m.head().test());
127   return _m.head().invalid();
128 }
129
130 PUBLIC inline NEEDS["kdb_ke.h"]
131 void
132 Queue::invalidate()
133 {
134   assert_kdb (_m.head().test());
135   _m.head().invalidate();
136 }
137