]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/l4re/include/event
Update
[l4.git] / l4 / pkg / l4re-core / l4re / include / event
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  *               Alexander Warg <warg@os.inf.tu-dresden.de>
5  *     economic rights: Technische Universität Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  *
11  * As a special exception, you may use this file as part of a free software
12  * library without restriction.  Specifically, if other files instantiate
13  * templates or use macros or inline functions from this file, or you compile
14  * this file and link it with other files to produce an executable, this
15  * file does not by itself cause the resulting executable to be covered by
16  * the GNU General Public License.  This exception does not however
17  * invalidate any other reasons why the executable file might be covered by
18  * the GNU General Public License.
19  */
20
21 #pragma once
22
23 #include <l4/sys/capability>
24 #include <l4/sys/irq>
25 #include <l4/sys/cxx/ipc_iface>
26 #include <l4/sys/cxx/ipc_array>
27 #include <l4/re/dataspace>
28 #include <l4/re/event.h>
29
30 namespace L4Re {
31
32 /**
33  * \defgroup api_l4re_event Event API
34  * \ingroup api_l4re
35  * \brief Event interface.
36  */
37
38 typedef l4re_event_stream_id_t Event_stream_id;
39 typedef l4re_event_absinfo_t Event_absinfo;
40
41 class L4_EXPORT Event_stream_bitmap_h
42 {
43 protected:
44   static unsigned __get_idx(unsigned idx)
45   { return idx / (sizeof(unsigned long)*8); }
46
47   static unsigned long __get_mask(unsigned idx)
48   { return 1ul << (idx % (sizeof(unsigned long)*8)); }
49
50   static bool __get_bit(unsigned long const *bm, unsigned max, unsigned idx)
51   {
52     if (idx <= max)
53       return bm[__get_idx(idx)] & __get_mask(idx);
54     return false;
55   }
56
57   static void __set_bit(unsigned long *bm, unsigned max, unsigned idx, bool v)
58   {
59     if (idx > max)
60       return;
61
62     if (v)
63       bm[__get_idx(idx)] |= __get_mask(idx);
64     else
65       bm[__get_idx(idx)] &= ~__get_mask(idx);
66   }
67 };
68
69 class L4_EXPORT Event_stream_info
70 : public l4re_event_stream_info_t,
71   private Event_stream_bitmap_h
72 {
73 public:
74   bool get_propbit(unsigned idx) const
75   { return __get_bit(propbits, L4RE_EVENT_PROP_MAX, idx); }
76
77   void set_propbit(unsigned idx, bool v)
78   { __set_bit(propbits, L4RE_EVENT_PROP_MAX, idx, v); }
79
80   bool get_evbit(unsigned idx) const
81   { return __get_bit(evbits, L4RE_EVENT_EV_MAX, idx); }
82
83   void set_evbit(unsigned idx, bool v)
84   { __set_bit(evbits, L4RE_EVENT_EV_MAX, idx, v); }
85
86   bool get_keybit(unsigned idx) const
87   { return __get_bit(keybits, L4RE_EVENT_KEY_MAX, idx); }
88
89   void set_keybit(unsigned idx, bool v)
90   { __set_bit(keybits, L4RE_EVENT_KEY_MAX, idx, v); }
91
92   bool get_relbit(unsigned idx) const
93   { return __get_bit(relbits, L4RE_EVENT_REL_MAX, idx); }
94
95   void set_relbit(unsigned idx, bool v)
96   { __set_bit(relbits, L4RE_EVENT_REL_MAX, idx, v); }
97
98   bool get_absbit(unsigned idx) const
99   { return __get_bit(absbits, L4RE_EVENT_ABS_MAX, idx); }
100
101   void set_absbit(unsigned idx, bool v)
102   { __set_bit(absbits, L4RE_EVENT_ABS_MAX, idx, v); }
103
104   bool get_swbit(unsigned idx) const
105   { return __get_bit(swbits, L4RE_EVENT_SW_MAX, idx); }
106
107   void set_swbit(unsigned idx, bool v)
108   { __set_bit(swbits, L4RE_EVENT_SW_MAX, idx, v); }
109 };
110
111 class L4_EXPORT Event_stream_state
112 : public l4re_event_stream_state_t,
113   private Event_stream_bitmap_h
114 {
115 public:
116   bool get_keybit(unsigned idx) const
117   { return __get_bit(keybits, L4RE_EVENT_KEY_MAX, idx); }
118
119   void set_keybit(unsigned idx, bool v)
120   { __set_bit(keybits, L4RE_EVENT_KEY_MAX, idx, v); }
121
122   bool get_swbit(unsigned idx) const
123   { return __get_bit(swbits, L4RE_EVENT_SW_MAX, idx); }
124
125   void set_swbit(unsigned idx, bool v)
126   { __set_bit(swbits, L4RE_EVENT_SW_MAX, idx, v); }
127 };
128
129 /**
130  * \brief Event class.
131  * \ingroup api_l4re_event
132  */
133 class L4_EXPORT Event :
134   public L4::Kobject_t<Event, L4::Icu, L4RE_PROTO_EVENT>
135 {
136 public:
137   /**
138    * \brief Get event signal buffer.
139    *
140    * \retval ds Event buffer.
141    *
142    * \return 0 on success, negative error code otherwise.
143    */
144   L4_RPC(long, get_buffer, (L4::Ipc::Out<L4::Cap<Dataspace> > ds));
145   L4_RPC(long, get_num_streams, ());
146   L4_RPC(long, get_stream_info, (int idx, Event_stream_info *info));
147   L4_RPC(long, get_stream_info_for_id, (l4_umword_t stream_id, Event_stream_info *info));
148   L4_RPC_NF(long, get_axis_info, (l4_umword_t stream_id,
149                                   L4::Ipc::Array<unsigned const, unsigned long> axes,
150                                   L4::Ipc::Array<Event_absinfo, unsigned long> &info));
151
152   long get_axis_info(l4_umword_t stream_id, unsigned naxes,
153                      unsigned const *axis, Event_absinfo *info) const throw()
154   {
155     L4::Ipc::Array<Event_absinfo, unsigned long> i(naxes, info);
156     return get_axis_info_t::call(c(), stream_id,
157         L4::Ipc::Array<unsigned const, unsigned long>(naxes, axis), i);
158   }
159
160   L4_RPC(long, get_stream_state_for_id, (l4_umword_t stream_id,
161                                          Event_stream_state *state));
162
163   typedef L4::Typeid::Rpcs<
164     get_buffer_t,
165     get_num_streams_t,
166     get_stream_info_t,
167     get_stream_info_for_id_t,
168     get_axis_info_t,
169     get_stream_state_for_id_t
170   > Rpcs;
171 };
172
173 struct L4_EXPORT Default_event_payload
174 {
175   unsigned short type;    /**< Type of event */
176   unsigned short code;    /**< Code of event */
177   int value;              /**< Value of event */
178   l4_umword_t stream_id;  /**< Stream ID */
179 };
180
181
182 /**
183  * \brief Event buffer class.
184  * \ingroup api_l4re_event
185  */
186 template< typename PAYLOAD = Default_event_payload >
187 class L4_EXPORT Event_buffer_t
188 {
189 public:
190
191   /**
192    * \brief Event structure used in buffer.
193    */
194   struct Event
195   {
196     long long time;         /**< Event time stamp */
197     PAYLOAD payload;
198
199     /**
200      * \brief Free the entry.
201      */
202     void free() throw() { l4_mb(); time = 0; }
203   };
204
205 private:
206   Event *_current;
207   Event *_begin;
208   Event const *_end;
209
210   void inc() throw()
211   {
212     ++_current;
213     if (_current == _end)
214       _current = _begin;
215   }
216
217 public:
218
219   Event_buffer_t() : _current(0), _begin(0), _end(0) {}
220
221   void reset()
222   {
223     for (Event *i = _begin; i != _end; ++i)
224       i->time = 0;
225     _current = _begin;
226   }
227
228   /**
229    * \brief Initialize event buffer.
230    *
231    * \param buffer   Pointer to buffer.
232    * \param size     Size of buffer in bytes.
233    */
234   Event_buffer_t(void *buffer, l4_addr_t size)
235     : _current((Event*)buffer), _begin(_current),
236       _end(_begin + size / sizeof(Event))
237   { reset(); }
238
239   /**
240    * \brief Next event in buffer.
241    *
242    * \return 0 if no event available, event otherwise.
243    */
244   Event *next() throw()
245   {
246     Event *c = _current;
247     if (c->time)
248       {
249         inc();
250         return c;
251       }
252     return 0;
253   }
254
255   /**
256    * \brief Put event into buffer at current position.
257    *
258    * \param ev   Event to put into the buffer.
259    * \return false if buffer is full and entry could not be added.
260    */
261   bool put(Event const &ev) throw()
262   {
263     Event *c = _current;
264     if (c->time)
265       return false;
266
267     inc();
268     c->payload = ev.payload;
269     l4_wmb();
270     c->time = ev.time;
271     return true;
272   }
273 };
274
275 typedef Event_buffer_t<Default_event_payload> Event_buffer;
276
277 }
278
279