vcl: support for eventfd mq signaling
[vpp.git] / src / svm / message_queue.h
index 4c16c97..28bf14e 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <vppinfra/clib.h>
 #include <vppinfra/error.h>
-#include <vppinfra/time.h>
 #include <svm/queue.h>
 
 typedef struct svm_msg_q_ring_
@@ -214,6 +213,40 @@ void *svm_msg_q_msg_data (svm_msg_q_t * mq, svm_msg_q_msg_t * msg);
  */
 svm_msg_q_ring_t *svm_msg_q_ring (svm_msg_q_t * mq, u32 ring_index);
 
+/**
+ * Set event fd for queue consumer
+ *
+ * If set, queue will exclusively use eventfds for signaling. Moreover,
+ * afterwards, the queue should only be used in non-blocking mode. Waiting
+ * for events should be done externally using something like epoll.
+ *
+ * @param mq           message queue
+ * @param fd           consumer eventfd
+ */
+void svm_msg_q_set_consumer_eventfd (svm_msg_q_t * mq, int fd);
+
+/**
+ * Set event fd for queue producer
+ *
+ * If set, queue will exclusively use eventfds for signaling. Moreover,
+ * afterwards, the queue should only be used in non-blocking mode. Waiting
+ * for events should be done externally using something like epoll.
+ *
+ * @param mq           message queue
+ * @param fd           producer eventfd
+ */
+void svm_msg_q_set_producer_eventfd (svm_msg_q_t * mq, int fd);
+
+/**
+ * Allocate event fd for queue consumer
+ */
+int svm_msg_q_alloc_consumer_eventfd (svm_msg_q_t * mq);
+
+/**
+ * Allocate event fd for queue consumer
+ */
+int svm_msg_q_alloc_producer_eventfd (svm_msg_q_t * mq);
+
 /**
  * Check if message queue is full
  */
@@ -290,12 +323,13 @@ svm_msg_q_unlock (svm_msg_q_t * mq)
 /**
  * Wait for message queue event
  *
- * Must be called with mutex held
+ * Must be called with mutex held. The queue only works non-blocking
+ * with eventfds, so handle blocking calls as an exception here.
  */
 static inline void
 svm_msg_q_wait (svm_msg_q_t * mq)
 {
-  pthread_cond_wait (&mq->q->condvar, &mq->q->mutex);
+  svm_queue_wait (mq->q);
 }
 
 /**
@@ -309,13 +343,19 @@ svm_msg_q_wait (svm_msg_q_t * mq)
 static inline int
 svm_msg_q_timedwait (svm_msg_q_t * mq, double timeout)
 {
-  struct timespec ts;
+  return svm_queue_timedwait (mq->q, timeout);
+}
+
+static inline int
+svm_msg_q_get_consumer_eventfd (svm_msg_q_t * mq)
+{
+  return mq->q->consumer_evtfd;
+}
 
-  ts.tv_sec = unix_time_now () + (u32) timeout;
-  ts.tv_nsec = (timeout - (u32) timeout) * 1e9;
-  if (pthread_cond_timedwait (&mq->q->condvar, &mq->q->mutex, &ts))
-    return -1;
-  return 0;
+static inline int
+svm_msg_q_get_producer_eventfd (svm_msg_q_t * mq)
+{
+  return mq->q->producer_evtfd;
 }
 
 #endif /* SRC_SVM_MESSAGE_QUEUE_H_ */