]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/__timeout.h
5f2469fafa0f68999933a062307146087bfcf292
[l4.git] / l4 / pkg / l4sys / include / __timeout.h
1 /**
2  * \internal
3  * \file
4  * \brief   Timeout definitions.
5  */
6 /*
7  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
9  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
10  *     economic rights: Technische Universität Dresden (Germany)
11  *
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  *
16  * As a special exception, you may use this file as part of a free software
17  * library without restriction.  Specifically, if other files instantiate
18  * templates or use macros or inline functions from this file, or you compile
19  * this file and link it with other files to produce an executable, this
20  * file does not by itself cause the resulting executable to be covered by
21  * the GNU General Public License.  This exception does not however
22  * invalidate any other reasons why the executable file might be covered by
23  * the GNU General Public License.
24  */
25 #ifndef L4_SYS_TIMEOUT_H__
26 #define L4_SYS_TIMEOUT_H__
27
28 #include <l4/sys/l4int.h>
29
30 /**
31  * \defgroup l4_timeout_api Timeouts
32  * \ingroup l4_ipc_api
33  * \brief All kinds of timeouts and time related functions.
34  */
35
36 /**
37  * \brief Basic timeout specification.
38  * \ingroup l4_timeout_api
39  *
40  * Basically a floating point number with 10 bits mantissa and
41  * 5 bits exponent (t = m*2^e).
42  *
43  * The timeout can also specify an absolute point in time (bit 16 == 1).
44  */
45 typedef struct l4_timeout_s {
46   l4_uint16_t t;                           /**< timeout value */
47 } __attribute__((packed)) l4_timeout_s;
48
49
50 /**
51  * \brief Timeout pair.
52  * \ingroup l4_timeout_api
53  *
54  * For IPC there are usually a send and a receive timeout.
55  * So this structure contains a pair of timeouts.
56  */
57 typedef union l4_timeout_t {
58   l4_uint32_t raw;                 /**< raw value */
59   struct
60   {
61 #ifdef __BIG_ENDIAN__
62     l4_timeout_s snd;              /**< send timeout */
63     l4_timeout_s rcv;              /**< receive timeout */
64 #else
65     l4_timeout_s rcv;              /**< receive timeout */
66     l4_timeout_s snd;              /**< send timeout */
67 #endif
68   } p;                             /**< combined timeout */
69 } l4_timeout_t;
70
71
72 /**
73  * \brief Timeout constants.
74  * \ingroup l4_timeout_api
75  */
76 /*@{*/
77 #define L4_IPC_TIMEOUT_0 ((l4_timeout_s){0x0400})           /**< 0 timeout */
78 #define L4_IPC_TIMEOUT_NEVER ((l4_timeout_s){0})            /**< never timeout */
79 #define L4_IPC_NEVER_INITIALIZER {0}                        /**< never timeout, init */
80 #define L4_IPC_NEVER ((l4_timeout_t){0})                    /**< never timeout */
81 #define L4_IPC_RECV_TIMEOUT_0 ((l4_timeout_t){0x00000400})  /**< 0 receive timeout */
82 #define L4_IPC_SEND_TIMEOUT_0 ((l4_timeout_t){0x04000000})  /**< 0 send timeout */
83 #define L4_IPC_BOTH_TIMEOUT_0 ((l4_timeout_t){0x04000400})  /**< 0 receive and send timeout */
84 /*@}*/
85
86 /**
87  * \brief Intervals of validity for absolute timeouts
88  * \ingroup l4_timeout_api
89  *
90  * Times are actually 2^x values (e.g. 2ms -> 2048µs)
91  */
92 enum l4_timeout_abs_validity {
93   L4_TIMEOUT_ABS_V1_ms = 0,
94   L4_TIMEOUT_ABS_V2_ms,
95   L4_TIMEOUT_ABS_V4_ms,
96   L4_TIMEOUT_ABS_V8_ms,    /* 5 */
97   L4_TIMEOUT_ABS_V16_ms,
98   L4_TIMEOUT_ABS_V32_ms,
99   L4_TIMEOUT_ABS_V64_ms,
100   L4_TIMEOUT_ABS_V128_ms,
101   L4_TIMEOUT_ABS_V256_ms,  /* 10 */
102   L4_TIMEOUT_ABS_V512_ms,
103   L4_TIMEOUT_ABS_V1_s,
104   L4_TIMEOUT_ABS_V2_s,
105   L4_TIMEOUT_ABS_V4_s,
106   L4_TIMEOUT_ABS_V8_s,
107   L4_TIMEOUT_ABS_V16_s,
108   L4_TIMEOUT_ABS_V32_s,
109 };
110
111 /**
112  * \brief Get relative timeout consisting of mantissa and exponent.
113  * \ingroup l4_timeout_api
114  *
115  * \param  man Mantissa of timeout
116  * \param  exp Exponent of timeout
117  *
118  * \return timeout value
119  */
120 L4_INLINE
121 l4_timeout_s l4_timeout_rel(unsigned man, unsigned exp) L4_NOTHROW;
122
123
124 /**
125  * \brief Convert explicit timeout values to l4_timeout_t type.
126  * \ingroup l4_timeout_api
127  *
128  * \param  snd_man    Mantissa of send timeout.
129  * \param  snd_exp    Exponent of send timeout.
130  * \param  rcv_man    Mantissa of receive timeout.
131  * \param  rcv_exp    Exponent of receive timeout.
132  */
133 L4_INLINE
134 l4_timeout_t l4_ipc_timeout(unsigned snd_man, unsigned snd_exp,
135                             unsigned rcv_man, unsigned rcv_exp) L4_NOTHROW;
136
137 /**
138  * \brief Combine send and receive timeout in a timeout.
139  * \ingroup l4_timeout_api
140  *
141  * \param  snd    Send timeout
142  * \param  rcv    Receive timeout
143  *
144  * \return L4 timeout
145  */
146 L4_INLINE
147 l4_timeout_t l4_timeout(l4_timeout_s snd, l4_timeout_s rcv) L4_NOTHROW;
148
149 /**
150  * \brief Set send timeout in given to timeout.
151  * \ingroup l4_timeout_api
152  *
153  * \param  snd    Send timeout
154  * \retval to     L4 timeout
155  */
156 L4_INLINE
157 void l4_snd_timeout(l4_timeout_s snd, l4_timeout_t *to) L4_NOTHROW;
158
159 /**
160  * \brief Set receive timeout in given to timeout.
161  * \ingroup l4_timeout_api
162  *
163  * \param  rcv    Receive timeout
164  * \retval to     L4 timeout
165  */
166 L4_INLINE
167 void l4_rcv_timeout(l4_timeout_s rcv, l4_timeout_t *to) L4_NOTHROW;
168
169 /**
170  * \brief Get clock value of out timeout.
171  * \ingroup l4_timeout_api
172  *
173  * \param to     L4 timeout
174  *
175  * \return Clock value
176  */
177 L4_INLINE
178 l4_kernel_clock_t l4_timeout_rel_get(l4_timeout_s to) L4_NOTHROW;
179
180
181 /**
182  * \brief Return whether the given timeout is absolute or not.
183  * \ingroup l4_timeout_api
184  *
185  * \param to     L4 timeout
186  *
187  * \return != 0 if absolute, 0 if relative
188  */
189 L4_INLINE
190 unsigned l4_timeout_is_absolute(l4_timeout_s to) L4_NOTHROW;
191
192 /**
193  * \brief Get clock value for a clock + a timeout.
194  * \ingroup l4_timeout_api
195  *
196  * \param cur    Clock value
197  * \param to     L4 timeout
198  *
199  * \return Clock sum
200  */
201 L4_INLINE
202 l4_kernel_clock_t l4_timeout_get(l4_kernel_clock_t cur, l4_timeout_s to) L4_NOTHROW;
203
204
205 /*
206  * Implementation
207  */
208
209 L4_INLINE
210 l4_timeout_t l4_ipc_timeout(unsigned snd_man, unsigned snd_exp,
211     unsigned rcv_man, unsigned rcv_exp) L4_NOTHROW
212 {
213   l4_timeout_t t;
214   t.p.snd.t = (snd_man & 0x3ff) | ((snd_exp << 10) & 0x7c00);
215   t.p.rcv.t = (rcv_man & 0x3ff) | ((rcv_exp << 10) & 0x7c00);
216   return t;
217 }
218
219
220 L4_INLINE
221 l4_timeout_t l4_timeout(l4_timeout_s snd, l4_timeout_s rcv) L4_NOTHROW
222 {
223   l4_timeout_t t;
224   t.p.snd = snd;
225   t.p.rcv = rcv;
226   return t;
227 }
228
229
230 L4_INLINE
231 void l4_snd_timeout(l4_timeout_s snd, l4_timeout_t *to) L4_NOTHROW
232 {
233   to->p.snd = snd;
234 }
235
236
237 L4_INLINE
238 void l4_rcv_timeout(l4_timeout_s rcv, l4_timeout_t *to) L4_NOTHROW
239 {
240   to->p.rcv = rcv;
241 }
242
243
244 L4_INLINE
245 l4_timeout_s l4_timeout_rel(unsigned man, unsigned exp) L4_NOTHROW
246 {
247   return (l4_timeout_s){(l4_uint16_t)((man & 0x3ff) | ((exp << 10) & 0x7c00))};
248 }
249
250
251 L4_INLINE
252 l4_kernel_clock_t l4_timeout_rel_get(l4_timeout_s to) L4_NOTHROW
253 {
254   if (to.t == 0)
255     return ~0ULL;
256   return (l4_kernel_clock_t)(to.t & 0x3ff) << ((to.t >> 10) & 0x1f);
257 }
258
259
260 L4_INLINE
261 unsigned l4_timeout_is_absolute(l4_timeout_s to) L4_NOTHROW
262 {
263   return to.t & 0x8000;
264 }
265
266
267 L4_INLINE
268 l4_kernel_clock_t l4_timeout_get(l4_kernel_clock_t cur, l4_timeout_s to) L4_NOTHROW
269 {
270   if (l4_timeout_is_absolute(to))
271     return 0; /* We cannot retrieve the value ... */
272   else
273     return cur + l4_timeout_rel_get(to);
274 }
275
276
277 #endif