summaryrefslogtreecommitdiffstats
path: root/src/svm
diff options
context:
space:
mode:
authorMohsin Kazmi <sykazmi@cisco.com>2018-01-04 18:57:26 +0100
committerDave Barach <openvpp@barachs.net>2018-01-22 18:17:23 +0000
commit3fca567ff438145e28dd1318ad5b1734c1091257 (patch)
tree7101b4ae130f2731e549f82ab98af8bfbabc6571 /src/svm
parente82488f10f20f464961c5c7b381b4a419bca0bbc (diff)
svm: queue sub: Add conditional timed wait
On reviece side svm queue only permits blocking and non-blocking calls. This patch adds timed wait blocking functionality which returns either on signal/event or on given time out. It also preserves the original behavior, so it will not hurt client applications which are using svm queue. Change-Id: Ic10632170330a80afb8bc781d4ccddfe4da2c69a Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/svm')
-rw-r--r--src/svm/queue.c31
-rw-r--r--src/svm/queue.h21
2 files changed, 46 insertions, 6 deletions
diff --git a/src/svm/queue.c b/src/svm/queue.c
index aef409277db..96e40fc2aec 100644
--- a/src/svm/queue.c
+++ b/src/svm/queue.c
@@ -26,6 +26,7 @@
#include <vppinfra/format.h>
#include <vppinfra/cache.h>
#include <svm/queue.h>
+#include <vppinfra/time.h>
#include <signal.h>
/*
@@ -299,12 +300,14 @@ svm_queue_add2 (svm_queue_t * q, u8 * elem, u8 * elem2, int nowait)
* svm_queue_sub
*/
int
-svm_queue_sub (svm_queue_t * q, u8 * elem, int nowait)
+svm_queue_sub (svm_queue_t * q, u8 * elem, svm_q_conditional_wait_t cond,
+ u32 time)
{
i8 *headp;
int need_broadcast = 0;
+ int rc = 0;
- if (nowait)
+ if (cond == SVM_Q_NOWAIT)
{
/* zero on success */
if (pthread_mutex_trylock (&q->mutex))
@@ -317,14 +320,32 @@ svm_queue_sub (svm_queue_t * q, u8 * elem, int nowait)
if (PREDICT_FALSE (q->cursize == 0))
{
- if (nowait)
+ if (cond == SVM_Q_NOWAIT)
{
pthread_mutex_unlock (&q->mutex);
return (-2);
}
- while (q->cursize == 0)
+ else if (cond == SVM_Q_TIMEDWAIT)
{
- (void) pthread_cond_wait (&q->condvar, &q->mutex);
+ struct timespec ts;
+ ts.tv_sec = unix_time_now () + time;
+ ts.tv_nsec = 0;
+ while (q->cursize == 0 && rc == 0)
+ {
+ rc = pthread_cond_timedwait (&q->condvar, &q->mutex, &ts);
+ }
+ if (rc == ETIMEDOUT)
+ {
+ pthread_mutex_unlock (&q->mutex);
+ return ETIMEDOUT;
+ }
+ }
+ else
+ {
+ while (q->cursize == 0)
+ {
+ (void) pthread_cond_wait (&q->condvar, &q->mutex);
+ }
}
}
diff --git a/src/svm/queue.h b/src/svm/queue.h
index dc1fc36e002..856c17237d1 100644
--- a/src/svm/queue.h
+++ b/src/svm/queue.h
@@ -36,6 +36,24 @@ typedef struct _svm_queue
char data[0];
} svm_queue_t;
+typedef enum
+{
+ /**
+ * blocking call
+ */
+ SVM_Q_WAIT = 0,
+
+ /**
+ * non-blocking call
+ */
+ SVM_Q_NOWAIT,
+
+ /**
+ * blocking call, return on signal or time-out
+ */
+ SVM_Q_TIMEDWAIT,
+} svm_q_conditional_wait_t;
+
svm_queue_t *svm_queue_init (int nels,
int elsize,
int consumer_pid,
@@ -43,7 +61,8 @@ svm_queue_t *svm_queue_init (int nels,
void svm_queue_free (svm_queue_t * q);
int svm_queue_add (svm_queue_t * q, u8 * elem, int nowait);
int svm_queue_add2 (svm_queue_t * q, u8 * elem, u8 * elem2, int nowait);
-int svm_queue_sub (svm_queue_t * q, u8 * elem, int nowait);
+int svm_queue_sub (svm_queue_t * q, u8 * elem, svm_q_conditional_wait_t cond,
+ u32 time);
int svm_queue_sub2 (svm_queue_t * q, u8 * elem);
void svm_queue_lock (svm_queue_t * q);
void svm_queue_unlock (svm_queue_t * q);