]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/sender.cpp
update
[l4.git] / kernel / fiasco / src / kern / sender.cpp
1 INTERFACE:
2
3 #include "l4_types.h"
4 #include "prio_list.h"
5
6 class Receiver;
7
8 /** A sender.  This is a role class, so real senders need to inherit from it.
9  */
10 class Sender : private Prio_list_elem
11 {
12   MEMBER_OFFSET();
13 public:
14   /** Receiver-ready callback.  Receivers make sure to call this
15       function on waiting senders when they get ready to receive a
16       message from that sender.  Senders need to overwrite this interface. */
17   virtual void ipc_send_msg(Receiver *) = 0;
18   virtual void ipc_receiver_aborted() = 0;
19   virtual void modify_label(Mword const *todo, int cnt) = 0;
20
21
22 protected:
23   Receiver *_receiver;
24
25 private:
26
27   friend class Jdb;
28   friend class Jdb_thread_list;
29 };
30
31
32 IMPLEMENTATION:
33
34 #include <cassert>
35
36 #include "atomic.h"
37 #include "cpu_lock.h"
38 #include "lock_guard.h"
39 #include "mem.h"
40
41 //
42 // state requests/manipulation
43 //
44
45 /** Optimized constructor.  This constructor assumes that the object storage
46     is zero-initialized.
47     @param id user-visible thread ID of the sender
48     @param ignored an integer argument.  The value doesn't matter and 
49                    is used just to distinguish this constructor from the 
50                    default one.
51  */
52 PROTECTED inline
53 explicit
54 Sender::Sender (int /*ignored*/)
55 : _receiver(0)
56 {}
57
58
59 /** Current receiver.
60     @return receiver this sender is currently trying to send a message to.
61  */
62 PUBLIC inline
63 Receiver *
64 Sender::receiver() const
65 {
66   return _receiver;
67 }
68
69 /** Set current receiver.
70     @param receiver the receiver we're going to send a message to
71  */
72 PROTECTED inline
73 void
74 Sender::set_receiver(Receiver* receiver)
75 {
76   _receiver = receiver;
77 }
78
79 PUBLIC inline
80 unsigned short Sender::sender_prio()
81 {
82   return Prio_list_elem::prio();
83 }
84
85 /** Sender in a queue of senders?.
86     @return true if sender has enqueued in a receiver's list of waiting 
87             senders
88  */
89 PUBLIC inline
90 bool
91 Sender::in_sender_list() const
92 {
93   return Prio_list_elem::in_list();
94 }
95
96 PUBLIC inline
97 bool
98 Sender::is_head_of(Prio_list const *l) const
99 { return l->head() == this; }
100
101
102 PUBLIC static inline
103 Sender *
104 Sender::cast(Prio_list_elem *e)
105 { return static_cast<Sender*>(e); }
106
107
108 PUBLIC
109 //PROTECTED inline NEEDS [<cassert>, "cpu_lock.h", "lock_guard.h",
110 //                      Sender::replace_node, Sender::tree_insert]
111 void Sender::sender_enqueue(Prio_list *head, unsigned short prio)
112 {
113   assert(prio < 256);
114
115   Lock_guard<Cpu_lock> guard (&cpu_lock);
116   head->insert(this, prio);
117 }
118
119 //PUBLIC inline NEEDS [<cassert>, "cpu_lock.h", "lock_guard.h",
120 //                   Sender::remove_tree_elem, Sender::remove_head]
121 PUBLIC template< typename P_LIST >
122 void Sender::sender_dequeue(P_LIST list)
123 {
124
125   if (!in_sender_list())
126     return;
127
128   Lock_guard<Cpu_lock> guard (&cpu_lock);
129   list->dequeue(this);
130 }
131
132 // An special version, only to remove the head
133 // this is neccessary if the receiver removes the old know head
134 // after an unsuccessful ipc_receiver_ready.
135 PUBLIC template< typename P_LIST >
136 void Sender::sender_dequeue_head(P_LIST list)
137 {
138
139   if (!in_sender_list())
140     return;
141
142   Lock_guard<Cpu_lock> guard (&cpu_lock);
143
144   if (this == list->head())
145     list->dequeue(this);
146 }
147
148 PROTECTED template<typename P_LIST >
149 void Sender::sender_update_prio(P_LIST list, unsigned short newprio)
150 {
151   if(EXPECT_FALSE(sender_prio() == newprio))
152     return;
153
154   Lock_guard<Cpu_lock> guard (&cpu_lock);
155
156   if (!in_sender_list())
157     return;
158
159   sender_dequeue(list);
160   sender_enqueue(list, newprio);
161 }
162
163 /** Constructor.
164     @param id user-visible thread ID of the sender
165  */
166 PROTECTED inline
167 Sender::Sender()
168 {}
169