Messages received multiple times in QNX when IPU2 + DSP1/IPU1 are active
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / ipc / hlos / knl / transports / virtio / VirtQueue.c
index 94f210d0205b7289e275073cdb24289383c88871..1461179f17de28266bbeb12a1c81c388c2377265 100644 (file)
@@ -69,6 +69,7 @@
 #include "virtio_ring.h"
 #include "_rpmsg.h"
 #include <ipu_pm.h>
+#include <pthread.h>
 
 /* Used for defining the size of the virtqueue registry */
 #define NUM_QUEUES                      2
@@ -103,6 +104,9 @@ typedef struct VirtQueue_Object {
 
     /* Private arg from user */
     void *                  arg;
+
+    /* Mutex to protect vrings from multi-thread access */
+    pthread_mutex_t         mutex;
 } VirtQueue_Object;
 
 static UInt numQueues = 0;
@@ -197,6 +201,8 @@ Int VirtQueue_addAvailBuf(VirtQueue_Handle vq, Void *buf, UInt32 len, Int16 head
 {
     UInt16 avail;
 
+    pthread_mutex_lock(&vq->mutex);
+
     if (vq->num_free == 0) {
         /* There's no more space */
         GT_setFailureReason (curTrace,
@@ -225,6 +231,8 @@ Int VirtQueue_addAvailBuf(VirtQueue_Handle vq, Void *buf, UInt32 len, Int16 head
         vq->vring.avail->idx++;
     }
 
+    pthread_mutex_unlock(&vq->mutex);
+
     return (vq->num_free);
 }
 
@@ -235,11 +243,15 @@ Int16 VirtQueue_getUsedBuf(VirtQueue_Object *vq, Void **buf)
 {
     UInt16 head;
 
+    pthread_mutex_lock(&vq->mutex);
+
     /* There's nothing available? */
     if (vq->last_used_idx == vq->vring.used->idx) {
         /* We need to know about added buffers */
         vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
 
+        pthread_mutex_unlock(&vq->mutex);
+
         return (-1);
     }
 
@@ -253,6 +265,8 @@ Int16 VirtQueue_getUsedBuf(VirtQueue_Object *vq, Void **buf)
     vq->last_used_idx++;
     vq->num_free++;
 
+    pthread_mutex_unlock(&vq->mutex);
+
     *buf = mapPAtoVA(vq, vq->vring.desc[head].addr);
 
     return (head);
@@ -393,6 +407,9 @@ VirtQueue_Handle VirtQueue_create (VirtQueue_callback callback, UInt16 procId,
         vq = NULL;
     }
 
+    /* Initialize mutex */
+    pthread_mutex_init(&vq->mutex, NULL);
+
     return (vq);
 }