FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
message_queue.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /**
16  * @file
17  * @brief Unidirectional shared-memory multi-ring message queue
18  */
19 
20 #ifndef SRC_SVM_MESSAGE_QUEUE_H_
21 #define SRC_SVM_MESSAGE_QUEUE_H_
22 
23 #include <vppinfra/clib.h>
24 #include <vppinfra/error.h>
25 #include <vppinfra/lock.h>
26 #include <svm/queue.h>
27 
28 typedef struct svm_msg_q_shr_queue_
29 {
30  pthread_mutex_t mutex; /* 8 bytes */
31  pthread_cond_t condvar; /* 8 bytes */
34  volatile u32 cursize;
38  u8 data[0];
40 
41 typedef struct svm_msg_q_queue_
42 {
43  svm_msg_q_shared_queue_t *shr; /**< pointer to shared queue */
44  int evtfd; /**< producer/consumer eventfd */
45  clib_spinlock_t lock; /**< private lock for multi-producer */
47 
48 typedef struct svm_msg_q_ring_shared_
49 {
50  volatile u32 cursize; /**< current size of the ring */
51  u32 nitems; /**< max size of the ring */
52  volatile u32 head; /**< current head (for dequeue) */
53  volatile u32 tail; /**< current tail (for enqueue) */
54  u32 elsize; /**< size of an element */
55  u8 data[0]; /**< chunk of memory for msg data */
57 
58 typedef struct svm_msg_q_ring_
59 {
60  u32 nitems; /**< max size of the ring */
61  u32 elsize; /**< size of an element */
62  svm_msg_q_ring_shared_t *shr; /**< ring in shared memory */
63 } __clib_packed svm_msg_q_ring_t;
64 
65 typedef struct svm_msg_q_shared_
66 {
67  u32 n_rings; /**< number of rings after q */
68  u32 pad; /**< 8 byte alignment for q */
69  svm_msg_q_shared_queue_t q[0]; /**< queue for exchanging messages */
70 } __clib_packed svm_msg_q_shared_t;
71 
72 typedef struct svm_msg_q_
73 {
74  svm_msg_q_queue_t q; /**< queue for exchanging messages */
75  svm_msg_q_ring_t *rings; /**< rings with message data*/
76 } __clib_packed svm_msg_q_t;
77 
78 typedef struct svm_msg_q_ring_cfg_
79 {
82  void *data;
84 
85 typedef struct svm_msg_q_cfg_
86 {
87  int consumer_pid; /**< pid of msg consumer */
88  u32 q_nitems; /**< msg queue size (not rings) */
89  u32 n_rings; /**< number of msg rings */
90  svm_msg_q_ring_cfg_t *ring_cfgs; /**< array of ring cfgs */
92 
93 typedef union
94 {
95  struct
96  {
97  u32 ring_index; /**< ring index, could be u8 */
98  u32 elt_index; /**< index in ring */
99  };
102 
103 #define SVM_MQ_INVALID_MSG { .as_u64 = ~0 }
104 
106 {
110 
111 /**
112  * Allocate message queue
113  *
114  * Allocates a message queue on the heap. Based on the configuration options,
115  * apart from the message queue this also allocates (one or multiple)
116  * shared-memory rings for the messages.
117  *
118  * @param cfg configuration options: queue len, consumer pid,
119  * ring configs
120  * @return message queue
121  */
125 
126 void svm_msg_q_attach (svm_msg_q_t *mq, void *smq_base);
127 
128 /**
129  * Cleanup mq's private data
130  */
131 void svm_msg_q_cleanup (svm_msg_q_t *mq);
132 
133 /**
134  * Free message queue
135  *
136  * @param mq message queue to be freed
137  */
138 void svm_msg_q_free (svm_msg_q_t * mq);
139 
140 /**
141  * Allocate message buffer
142  *
143  * Message is allocated on the first available ring capable of holding
144  * the requested number of bytes.
145  *
146  * @param mq message queue
147  * @param nbytes number of bytes needed for message
148  * @return message structure pointing to the ring and position
149  * allocated
150  */
152 
153 /**
154  * Allocate message buffer on ring
155  *
156  * Message is allocated, on requested ring. The caller MUST check that
157  * the ring is not full.
158  *
159  * @param mq message queue
160  * @param ring_index ring on which the allocation should occur
161  * @return message structure pointing to the ring and position
162  * allocated
163  */
165 
166 /**
167  * Lock message queue and allocate message buffer on ring
168  *
169  * This should be used when multiple writers/readers are expected to
170  * compete for the rings/queue. Message should be enqueued by calling
171  * @ref svm_msg_q_add_w_lock and the caller MUST unlock the queue once
172  * the message in enqueued.
173  *
174  * @param mq message queue
175  * @param ring_index ring on which the allocation should occur
176  * @param noblock flag that indicates if request should block
177  * @param msg pointer to message to be filled in
178  * @return 0 on success, negative number otherwise
179  */
181  u8 noblock, svm_msg_q_msg_t * msg);
182 
183 /**
184  * Free message buffer
185  *
186  * Marks message buffer on ring as free.
187  *
188  * @param mq message queue
189  * @param msg message to be freed
190  */
192 
193 /**
194  * Producer enqueue one message to queue
195  *
196  * Prior to calling this, the producer should've obtained a message buffer
197  * from one of the rings by calling @ref svm_msg_q_alloc_msg.
198  *
199  * @param mq message queue
200  * @param msg message (pointer to ring position) to be enqueued
201  * @param nowait flag to indicate if request is blocking or not
202  * @return success status
203  */
204 int svm_msg_q_add (svm_msg_q_t * mq, svm_msg_q_msg_t * msg, int nowait);
205 
206 /**
207  * Producer enqueue one message to queue with mutex held
208  *
209  * Prior to calling this, the producer should've obtained a message buffer
210  * from one of the rings by calling @ref svm_msg_q_alloc_msg. It assumes
211  * the queue mutex is held.
212  *
213  * @param mq message queue
214  * @param msg message (pointer to ring position) to be enqueued
215  * @return success status
216  */
218 
219 /**
220  * Consumer dequeue one message from queue
221  *
222  * This returns the message pointing to the data in the message rings.
223  * Should only be used in single consumer scenarios as no locks are grabbed.
224  * The consumer is expected to call @ref svm_msg_q_free_msg once it
225  * finishes processing/copies the message data.
226  *
227  * @param mq message queue
228  * @param msg pointer to structure where message is to be received
229  * @param cond flag that indicates if request should block or not
230  * @param time time to wait if condition it SVM_Q_TIMEDWAIT
231  * @return success status
232  */
233 int svm_msg_q_sub (svm_msg_q_t * mq, svm_msg_q_msg_t * msg,
234  svm_q_conditional_wait_t cond, u32 time);
235 
236 /**
237  * Consumer dequeue one message from queue
238  *
239  * Returns the message pointing to the data in the message rings. Should only
240  * be used in single consumer scenarios as no locks are grabbed. The consumer
241  * is expected to call @ref svm_msg_q_free_msg once it finishes
242  * processing/copies the message data.
243  *
244  * @param mq message queue
245  * @param msg pointer to structure where message is to be received
246  * @return success status
247  */
249 
250 /**
251  * Consumer dequeue multiple messages from queue
252  *
253  * Returns the message pointing to the data in the message rings. Should only
254  * be used in single consumer scenarios as no locks are grabbed. The consumer
255  * is expected to call @ref svm_msg_q_free_msg once it finishes
256  * processing/copies the message data.
257  *
258  * @param mq message queue
259  * @param msg_buf pointer to array of messages to received
260  * @param n_msgs lengt of msg_buf array
261  * @return number of messages dequeued
262  */
264  u32 n_msgs);
265 
266 /**
267  * Get data for message in queue
268  *
269  * @param mq message queue
270  * @param msg message for which the data is requested
271  * @return pointer to data
272  */
274 
275 /**
276  * Get message queue ring
277  *
278  * @param mq message queue
279  * @param ring_index index of ring
280  * @return pointer to ring
281  */
282 svm_msg_q_ring_t *svm_msg_q_ring (svm_msg_q_t * mq, u32 ring_index);
283 
284 /**
285  * Set event fd for queue
286  *
287  * If set, queue will exclusively use eventfds for signaling. Moreover,
288  * afterwards, the queue should only be used in non-blocking mode. Waiting
289  * for events should be done externally using something like epoll.
290  *
291  * @param mq message queue
292  * @param fd consumer eventfd
293  */
294 void svm_msg_q_set_eventfd (svm_msg_q_t *mq, int fd);
295 
296 /**
297  * Allocate event fd for queue
298  */
300 
301 /**
302  * Format message queue, shows msg count for each ring
303  */
304 u8 *format_svm_msg_q (u8 *s, va_list *args);
305 
306 /**
307  * Check length of message queue
308  */
309 static inline u32
311 {
312  return clib_atomic_load_relax_n (&mq->q.shr->cursize);
313 }
314 
315 /**
316  * Check if message queue is full
317  */
318 static inline u8
320 {
321  return (svm_msg_q_size (mq) == mq->q.shr->maxsize);
322 }
323 
324 static inline u8
326 {
327  svm_msg_q_ring_t *ring = vec_elt_at_index (mq->rings, ring_index);
328  return (clib_atomic_load_relax_n (&ring->shr->cursize) >= ring->nitems);
329 }
330 
331 /**
332  * Check if message queue is empty
333  */
334 static inline u8
336 {
337  return (svm_msg_q_size (mq) == 0);
338 }
339 
340 /**
341  * Check if message is invalid
342  */
343 static inline u8
345 {
346  return (msg->as_u64 == (u64) ~ 0);
347 }
348 
349 /**
350  * Try locking message queue
351  */
352 static inline int
354 {
355  if (mq->q.evtfd == -1)
356  {
357  int rv = pthread_mutex_trylock (&mq->q.shr->mutex);
358  if (PREDICT_FALSE (rv == EOWNERDEAD))
359  rv = pthread_mutex_consistent (&mq->q.shr->mutex);
360  return rv;
361  }
362  else
363  {
364  return !clib_spinlock_trylock (&mq->q.lock);
365  }
366 }
367 
368 /**
369  * Lock, or block trying, the message queue
370  */
371 static inline int
373 {
374  if (mq->q.evtfd == -1)
375  {
376  int rv = pthread_mutex_lock (&mq->q.shr->mutex);
377  if (PREDICT_FALSE (rv == EOWNERDEAD))
378  rv = pthread_mutex_consistent (&mq->q.shr->mutex);
379  return rv;
380  }
381  else
382  {
383  clib_spinlock_lock (&mq->q.lock);
384  return 0;
385  }
386 }
387 
388 /**
389  * Unlock message queue
390  */
391 static inline void
393 {
394  if (mq->q.evtfd == -1)
395  {
396  pthread_mutex_unlock (&mq->q.shr->mutex);
397  }
398  else
399  {
400  clib_spinlock_unlock (&mq->q.lock);
401  }
402 }
403 
404 /**
405  * Wait for message queue event
406  *
407  * When eventfds are not configured, the shared memory mutex is locked
408  * before waiting on the condvar. Typically called by consumers.
409  */
411 
412 /**
413  * Wait for message queue event as producer
414  *
415  * Similar to @ref svm_msg_q_wait but lock (mutex or spinlock) must
416  * be held. Should only be called by producers.
417  */
419 
420 /**
421  * Timed wait for message queue event
422  *
423  * Must be called with mutex held.
424  *
425  * @param mq message queue
426  * @param timeout time in seconds
427  */
428 int svm_msg_q_timedwait (svm_msg_q_t *mq, double timeout);
429 
430 static inline int
432 {
433  return mq->q.evtfd;
434 }
435 
436 #endif /* SRC_SVM_MESSAGE_QUEUE_H_ */
437 
438 /*
439  * fd.io coding-style-patch-verification: ON
440  *
441  * Local Variables:
442  * eval: (c-set-style "gnu")
443  * End:
444  */
svm_msg_q_size
static u32 svm_msg_q_size(svm_msg_q_t *mq)
Check length of message queue.
Definition: message_queue.h:310
svm_msg_q_shr_queue_::pad
u32 pad
Definition: message_queue.h:37
svm_msg_q_shared_
Definition: message_queue.h:65
svm_msg_q_cfg_::n_rings
u32 n_rings
number of msg rings
Definition: message_queue.h:89
svm_msg_q_queue_
Definition: message_queue.h:41
svm_msg_q_sub
int svm_msg_q_sub(svm_msg_q_t *mq, svm_msg_q_msg_t *msg, svm_q_conditional_wait_t cond, u32 time)
Consumer dequeue one message from queue.
Definition: message_queue.c:457
svm_msg_q_attach
void svm_msg_q_attach(svm_msg_q_t *mq, void *smq_base)
Definition: message_queue.c:144
svm_msg_q_add_and_unlock
void svm_msg_q_add_and_unlock(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Producer enqueue one message to queue with mutex held.
Definition: message_queue.c:394
svm_msg_q_shr_queue_::mutex
pthread_mutex_t mutex
Definition: message_queue.h:30
svm_msg_q_msg_t::as_u64
u64 as_u64
Definition: message_queue.h:100
svm_msg_q_ring_shared_
Definition: message_queue.h:48
svm_msg_q_ring_shared_::nitems
u32 nitems
max size of the ring
Definition: message_queue.h:51
svm_msg_q_alloc_msg
svm_msg_q_msg_t svm_msg_q_alloc_msg(svm_msg_q_t *mq, u32 nbytes)
Allocate message buffer.
Definition: message_queue.c:266
svm_msg_q_queue_t
struct svm_msg_q_queue_ svm_msg_q_queue_t
svm_msg_q_size_to_alloc
uword svm_msg_q_size_to_alloc(svm_msg_q_cfg_t *cfg)
Definition: message_queue.c:104
svm_msg_q_add
int svm_msg_q_add(svm_msg_q_t *mq, svm_msg_q_msg_t *msg, int nowait)
Producer enqueue one message to queue.
Definition: message_queue.c:363
svm_msg_q_shr_queue_::elsize
u32 elsize
Definition: message_queue.h:36
svm_msg_q_try_lock
static int svm_msg_q_try_lock(svm_msg_q_t *mq)
Try locking message queue.
Definition: message_queue.h:353
svm_msg_q_free_msg
void svm_msg_q_free_msg(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Free message buffer.
Definition: message_queue.c:294
clib.h
svm_msg_q_ring_cfg_::data
void * data
Definition: message_queue.h:82
svm_msg_q_ring_shared_::tail
volatile u32 tail
current tail (for enqueue)
Definition: message_queue.h:53
svm_msg_q_sub_raw_batch
int svm_msg_q_sub_raw_batch(svm_msg_q_t *mq, svm_msg_q_msg_t *msg_buf, u32 n_msgs)
Consumer dequeue multiple messages from queue.
Definition: message_queue.c:423
svm_msg_q_wait_prod
int svm_msg_q_wait_prod(svm_msg_q_t *mq)
Wait for message queue event as producer.
Definition: message_queue.c:543
svm_msg_q_cfg_::q_nitems
u32 q_nitems
msg queue size (not rings)
Definition: message_queue.h:88
svm_msg_q_lock
static int svm_msg_q_lock(svm_msg_q_t *mq)
Lock, or block trying, the message queue.
Definition: message_queue.h:372
svm_msg_q_msg_t::elt_index
u32 elt_index
index in ring
Definition: message_queue.h:98
svm_msg_q_msg_t
Definition: message_queue.h:93
svm_msg_q_wait_type_
svm_msg_q_wait_type_
Definition: message_queue.h:105
svm_msg_q_sub_raw
int svm_msg_q_sub_raw(svm_msg_q_t *mq, svm_msg_q_msg_t *elem)
Consumer dequeue one message from queue.
Definition: message_queue.c:402
svm_msg_q_ring_t
struct svm_msg_q_ring_ svm_msg_q_ring_t
svm_msg_q_ring_
Definition: message_queue.h:58
svm_msg_q_wait
int svm_msg_q_wait(svm_msg_q_t *mq, svm_msg_q_wait_type_t type)
Wait for message queue event.
Definition: message_queue.c:501
svm_msg_q_shared_::q
svm_msg_q_shared_queue_t q[0]
queue for exchanging messages
Definition: message_queue.h:69
svm_msg_q_cleanup
void svm_msg_q_cleanup(svm_msg_q_t *mq)
Cleanup mq's private data.
Definition: message_queue.c:170
svm_msg_q_ring_cfg_
Definition: message_queue.h:78
svm_msg_q_is_empty
static u8 svm_msg_q_is_empty(svm_msg_q_t *mq)
Check if message queue is empty.
Definition: message_queue.h:335
svm_msg_q_shr_queue_::data
u8 data[0]
Definition: message_queue.h:38
svm_msg_q_shared_t
struct svm_msg_q_shared_ svm_msg_q_shared_t
svm_msg_q_shr_queue_::tail
u32 tail
Definition: message_queue.h:33
svm_msg_q_is_full
static u8 svm_msg_q_is_full(svm_msg_q_t *mq)
Check if message queue is full.
Definition: message_queue.h:319
error.h
svm_msg_q_alloc
svm_msg_q_shared_t * svm_msg_q_alloc(svm_msg_q_cfg_t *cfg)
Allocate message queue.
Definition: message_queue.c:130
svm_msg_q_shr_queue_::head
u32 head
Definition: message_queue.h:32
svm_msg_q_shr_queue_::maxsize
u32 maxsize
Definition: message_queue.h:35
svm_msg_q_shr_queue_::condvar
pthread_cond_t condvar
Definition: message_queue.h:31
svm_msg_q_shared_queue_t
struct svm_msg_q_shr_queue_ svm_msg_q_shared_queue_t
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
svm_msg_q_msg_is_invalid
static u8 svm_msg_q_msg_is_invalid(svm_msg_q_msg_t *msg)
Check if message is invalid.
Definition: message_queue.h:344
svm_msg_q_ring_shared_::data
u8 data[0]
chunk of memory for msg data
Definition: message_queue.h:55
lock.h
svm_msg_q_queue_::shr
svm_msg_q_shared_queue_t * shr
pointer to shared queue
Definition: message_queue.h:43
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
svm_msg_q_msg_t::ring_index
u32 ring_index
ring index, could be u8
Definition: message_queue.h:97
clib_spinlock_lock
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:82
svm_msg_q_init
svm_msg_q_shared_t * svm_msg_q_init(void *base, svm_msg_q_cfg_t *cfg)
Definition: message_queue.c:72
clib_spinlock_s
Definition: lock.h:51
svm_msg_q_ring_cfg_::nitems
u32 nitems
Definition: message_queue.h:80
uword
u64 uword
Definition: types.h:112
svm_msg_q_ring_shared_t
struct svm_msg_q_ring_shared_ svm_msg_q_ring_shared_t
clib_spinlock_trylock
static_always_inline int clib_spinlock_trylock(clib_spinlock_t *p)
Definition: lock.h:97
svm_msg_q_queue_::evtfd
int evtfd
producer/consumer eventfd
Definition: message_queue.h:44
svm_msg_q_timedwait
int svm_msg_q_timedwait(svm_msg_q_t *mq, double timeout)
Timed wait for message queue event.
Definition: message_queue.c:572
svm_msg_q_shared_::pad
u32 pad
8 byte alignment for q
Definition: message_queue.h:68
svm_msg_q_cfg_::ring_cfgs
svm_msg_q_ring_cfg_t * ring_cfgs
array of ring cfgs
Definition: message_queue.h:90
n_msgs
n_msgs
Definition: application.c:506
svm_msg_q_shared_::n_rings
u32 n_rings
number of rings after q
Definition: message_queue.h:67
svm_msg_q_ring_shared_::elsize
u32 elsize
size of an element
Definition: message_queue.h:54
svm_msg_q_t
struct svm_msg_q_ svm_msg_q_t
svm_msg_q_ring_::nitems
u32 nitems
max size of the ring
Definition: message_queue.h:60
svm_msg_q_
Definition: message_queue.h:72
queue.h
svm_msg_q_ring_::shr
svm_msg_q_ring_shared_t * shr
ring in shared memory
Definition: message_queue.h:62
svm_msg_q_free
void svm_msg_q_free(svm_msg_q_t *mq)
Free message queue.
Definition: message_queue.c:179
svm_msg_q_alloc_msg_w_ring
svm_msg_q_msg_t svm_msg_q_alloc_msg_w_ring(svm_msg_q_t *mq, u32 ring_index)
Allocate message buffer on ring.
Definition: message_queue.c:221
svm_msg_q_shr_queue_
Definition: message_queue.h:28
svm_msg_q_ring_cfg_::elsize
u32 elsize
Definition: message_queue.h:81
svm_msg_q_msg_data
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
Definition: message_queue.c:287
svm_msg_q_lock_and_alloc_msg_w_ring
int svm_msg_q_lock_and_alloc_msg_w_ring(svm_msg_q_t *mq, u32 ring_index, u8 noblock, svm_msg_q_msg_t *msg)
Lock message queue and allocate message buffer on ring.
Definition: message_queue.c:239
u64
unsigned long u64
Definition: types.h:89
svm_msg_q_ring_shared_::cursize
volatile u32 cursize
current size of the ring
Definition: message_queue.h:50
u32
unsigned int u32
Definition: types.h:88
clib_atomic_load_relax_n
#define clib_atomic_load_relax_n(a)
Definition: atomics.h:50
svm_msg_q_ring_::elsize
u32 elsize
size of an element
Definition: message_queue.h:61
svm_msg_q_alloc_eventfd
int svm_msg_q_alloc_eventfd(svm_msg_q_t *mq)
Allocate event fd for queue.
Definition: message_queue.c:491
svm_msg_q_::rings
svm_msg_q_ring_t * rings
rings with message data
Definition: message_queue.h:75
clib_spinlock_unlock
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:121
svm_msg_q_cfg_t
struct svm_msg_q_cfg_ svm_msg_q_cfg_t
svm_msg_q_cfg_
Definition: message_queue.h:85
svm_msg_q_cfg_::consumer_pid
int consumer_pid
pid of msg consumer
Definition: message_queue.h:87
svm_msg_q_ring_cfg_t
struct svm_msg_q_ring_cfg_ svm_msg_q_ring_cfg_t
svm_msg_q_shr_queue_::cursize
volatile u32 cursize
Definition: message_queue.h:34
u8
unsigned char u8
Definition: types.h:56
svm_msg_q_ring
svm_msg_q_ring_t * svm_msg_q_ring(svm_msg_q_t *mq, u32 ring_index)
Get message queue ring.
Definition: message_queue.c:30
format_svm_msg_q
u8 * format_svm_msg_q(u8 *s, va_list *args)
Format message queue, shows msg count for each ring.
Definition: message_queue.c:628
rv
int __clib_unused rv
Definition: application.c:491
svm_msg_q_queue_::lock
clib_spinlock_t lock
private lock for multi-producer
Definition: message_queue.h:45
svm_msg_q_wait_type_t
enum svm_msg_q_wait_type_ svm_msg_q_wait_type_t
svm_msg_q_ring_is_full
static u8 svm_msg_q_ring_is_full(svm_msg_q_t *mq, u32 ring_index)
Definition: message_queue.h:325
SVM_MQ_WAIT_FULL
@ SVM_MQ_WAIT_FULL
Definition: message_queue.h:108
SVM_MQ_WAIT_EMPTY
@ SVM_MQ_WAIT_EMPTY
Definition: message_queue.h:107
svm_msg_q_set_eventfd
void svm_msg_q_set_eventfd(svm_msg_q_t *mq, int fd)
Set event fd for queue.
Definition: message_queue.c:485
svm_msg_q_::q
svm_msg_q_queue_t q
queue for exchanging messages
Definition: message_queue.h:74
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
svm_q_conditional_wait_t
svm_q_conditional_wait_t
Definition: queue.h:40
svm_msg_q_ring_shared_::head
volatile u32 head
current head (for dequeue)
Definition: message_queue.h:52
svm_msg_q_get_eventfd
static int svm_msg_q_get_eventfd(svm_msg_q_t *mq)
Definition: message_queue.h:431
svm_msg_q_unlock
static void svm_msg_q_unlock(svm_msg_q_t *mq)
Unlock message queue.
Definition: message_queue.h:392