EM-ODP  3.7.0
Event Machine on ODP
em_event_inline.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Nokia Solutions and Networks
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31  /**
32  * @file
33  * EM internal event functions
34  *
35  */
36 
37 #ifndef EM_EVENT_INLINE_H_
38 #define EM_EVENT_INLINE_H_
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /** Convert an EM-event into an ODP-event */
45 static inline odp_event_t
46 event_em2odp(em_event_t event)
47 {
48  /* Valid for both ESV enabled and disabled */
49  evhdl_t evhdl = {.event = event};
50 
51  return (odp_event_t)(uintptr_t)evhdl.evptr;
52 }
53 
54 /**
55  * Convert an ODP-event into an EM-event
56  *
57  * @note The returned EM-event does NOT contain the ESV event-generation-count
58  * evhdl_t::evgen! This must be set separately when using ESV.
59  */
60 static inline em_event_t
61 event_odp2em(odp_event_t odp_event)
62 {
63  /* Valid for both ESV enabled and disabled */
64 
65  /*
66  * Setting 'evhdl.event = odp_event' is equal to
67  * 'evhdl.evptr = odp_event, evhdl.evgen = 0'
68  * (evhdl.evgen still needs to be set when using ESV)
69  */
70  evhdl_t evhdl = {.event = (em_event_t)(uintptr_t)odp_event};
71 
72  return evhdl.event;
73 }
74 
75 /** Convert an array of EM-events into an array ODP-events */
76 static inline void
77 events_em2odp(const em_event_t events[/*in*/],
78  odp_event_t odp_events[/*out*/], const unsigned int num)
79 {
80  /* Valid for both ESV enabled and disabled */
81  const evhdl_t *const evhdls = (const evhdl_t *)events;
82 
83  for (unsigned int i = 0; i < num; i++)
84  odp_events[i] = (odp_event_t)(uintptr_t)evhdls[i].evptr;
85 }
86 
87 /**
88  * Convert an array of ODP-events into an array of EM-events
89  *
90  * @note The output EM-events do NOT contain the ESV event-generation-count
91  * evhdl_t::evgen! This must be set separately when using ESV.
92  */
93 static inline void
94 events_odp2em(const odp_event_t odp_events[/*in*/],
95  em_event_t events[/*out*/], const unsigned int num)
96 {
97  /* Valid for both ESV enabled and disabled */
98  evhdl_t *const evhdls = (evhdl_t *)events;
99 
100  /*
101  * Setting 'evhdls[i].event = odp_events[i]' is equal to
102  * 'evhdls[i].evptr = odp_events[i], evhdl[i].evgen = 0'
103  * (evhdls[i].evgen still needs to be set when using ESV)
104  */
105  for (unsigned int i = 0; i < num; i++)
106  evhdls[i].event = (em_event_t)(uintptr_t)odp_events[i];
107 }
108 
109 /**
110  * Convert an array of EM-events into an array of ODP-packets.
111  * The content must be known to be packets.
112  */
113 static inline void
114 events_em2pkt(const em_event_t events[/*in*/],
115  odp_packet_t odp_pkts[/*out*/], const unsigned int num)
116 {
117  /* Valid for both ESV enabled and disabled */
118  const evhdl_t *const evhdls = (const evhdl_t *)events;
119 
120  for (unsigned int i = 0; i < num; i++)
121  odp_pkts[i] = odp_packet_from_event((odp_event_t)(uintptr_t)evhdls[i].evptr);
122 }
123 
124 /**
125  * Convert an array of EM-events into an array of ODP-packets in-place (i.e.
126  * convert using the same memory area for output) when the event type is known
127  * for sure to be packets. Be careful!
128  *
129  * @return Pointer to odp packet table: odp_packet_t pkts[num]
130  * Uses the same memory area for the output of 'pkts[num]' as for
131  * the input 'events[num]' (thus overwrites 'events[num]' with
132  * 'pkts[num]').
133  */
134 static inline odp_packet_t *
135 events_em2pkt_inplace(em_event_t events[/*in*/], const unsigned int num)
136 {
137  /* Valid for both ESV enabled and disabled */
138  evhdl_t *const evhdls = (evhdl_t *)events;
139  odp_packet_t *const pkts = (odp_packet_t *)events; /* careful! */
140 
141  /* Careful! Overwrites events[num] with pkts[num] */
142  for (unsigned int i = 0; i < num; i++)
143  pkts[i] = odp_packet_from_event((odp_event_t)(uintptr_t)evhdls[i].evptr);
144 
145  return pkts;
146 }
147 
148 /**
149  * @brief Convert from a packet-event to event header
150  *
151  * It has to be known that the event is a packet before calling this function,
152  * otherwise use event_to_hdr().
153  *
154  * @param pkt_event EM event based on odp_packet_t
155  * @return event_hdr_t* Pointer to the event header
156  *
157  * Does NOT initialize the event header.
158  */
159 static inline event_hdr_t *
160 eventpkt_to_hdr(em_event_t pkt_event)
161 {
162  odp_event_t odp_event = event_em2odp(pkt_event);
163  odp_packet_t odp_pkt = odp_packet_from_event(odp_event);
164  event_hdr_t *ev_hdr = odp_packet_user_area(odp_pkt);
165 
166  return ev_hdr;
167 }
168 
169 /**
170  * @brief Convert from a buffer-event to event header
171  *
172  * It has to be known that the event is a buffer before calling this function,
173  * otherwise use event_to_hdr().
174  *
175  * @param buf_event EM event based on odp_buffer_t
176  * @return event_hdr_t* Pointer to the event header
177  *
178  * Does NOT initialize the event header.
179  */
180 static inline event_hdr_t *
181 eventbuf_to_hdr(em_event_t buf_event)
182 {
183  odp_event_t odp_event = event_em2odp(buf_event);
184  odp_buffer_t odp_buf = odp_buffer_from_event(odp_event);
185  event_hdr_t *ev_hdr = odp_buffer_user_area(odp_buf);
186 
187  return ev_hdr;
188 }
189 
190 /**
191  * @brief Convert from an event vector to event header
192  *
193  * It has to be known that the event is a vector before calling this function,
194  * otherwise use event_to_hdr().
195  *
196  * @param vector_event EM event of major type EM_EVENT_TYPE_VECTOR
197  * @return event_hdr_t* Pointer to the event header
198  *
199  * Does NOT initialize the event header.
200  */
201 static inline event_hdr_t *
202 eventvec_to_hdr(em_event_t vector_event)
203 {
204  odp_event_t odp_event = event_em2odp(vector_event);
205  odp_packet_vector_t odp_pktvec = odp_packet_vector_from_event(odp_event);
206  event_hdr_t *ev_hdr = odp_packet_vector_user_area(odp_pktvec);
207 
208  return ev_hdr;
209 }
210 
211 /**
212  * Convert from EM event to event header.
213  *
214  * Does NOT initialize the event header.
215  */
216 static inline event_hdr_t *
217 event_to_hdr(em_event_t event)
218 {
219  odp_event_t odp_event = event_em2odp(event);
220  odp_packet_t odp_pkt;
221  odp_buffer_t odp_buf;
222  odp_timeout_t odp_tmo;
223  odp_packet_vector_t odp_pktvec;
224  event_hdr_t *ev_hdr;
225 
226  odp_event_type_t evtype = odp_event_type(odp_event);
227 
228  switch (evtype) {
229  case ODP_EVENT_PACKET:
230  odp_pkt = odp_packet_from_event(odp_event);
231  ev_hdr = odp_packet_user_area(odp_pkt);
232  break;
233  case ODP_EVENT_BUFFER:
234  odp_buf = odp_buffer_from_event(odp_event);
235  ev_hdr = odp_buffer_user_area(odp_buf);
236  break;
237  case ODP_EVENT_PACKET_VECTOR:
238  odp_pktvec = odp_packet_vector_from_event(odp_event);
239  ev_hdr = odp_packet_vector_user_area(odp_pktvec);
240  break;
241  case ODP_EVENT_TIMEOUT:
242  odp_tmo = odp_timeout_from_event(odp_event);
243  ev_hdr = odp_timeout_user_area(odp_tmo);
244  break;
245  default:
247  EM_ESCOPE_EVENT_TO_HDR,
248  "Unexpected odp event type:%u", evtype);
249  /* avoids: "error: 'ev_hdr' may be used uninitialized" */
250  __builtin_unreachable();
251  break;
252  }
253 
254  return ev_hdr;
255 }
256 
257 /**
258  * Convert from EM events to event headers.
259  *
260  * Does NOT initialize the event headers.
261  *
262  * @param[in] events Input array of 'num' valid events
263  * @param[out] ev_hdrs Output array with room to store 'num' pointers to the
264  * corresponding event headers
265  * @param num Number of entries in 'events[]' and 'ev_hdrs[]'
266  */
267 static inline void
268 event_to_hdr_multi(const em_event_t events[], event_hdr_t *ev_hdrs[/*out*/],
269  const int num)
270 {
271  for (int i = 0; i < num; i++)
272  ev_hdrs[i] = event_to_hdr(events[i]);
273 }
274 
275 /** Convert from event header to EM event */
276 static inline em_event_t
277 event_hdr_to_event(const event_hdr_t *const event_hdr)
278 {
279  return event_hdr->event;
280 }
281 
282 #ifdef __cplusplus
283 }
284 #endif
285 
286 #endif /* EM_EVENT_INLINE_H_ */
evhdl_t
Definition: em_event_types.h:67
event_hdr::event
em_event_t event
Definition: em_event_types.h:246
event_hdr
Definition: em_event_types.h:184
INTERNAL_ERROR
#define INTERNAL_ERROR(error, escope, fmt,...)
Definition: em_error.h:43
EM_ERR_NOT_IMPLEMENTED
@ EM_ERR_NOT_IMPLEMENTED
Definition: event_machine_hw_types.h:282