@@ -409,6 +409,21 @@ typedef struct odp_queue_info_t {
int odp_queue_info(odp_queue_t queue, odp_queue_info_t *info);
/**
+ * Retrieve current approximate depth of a queue
+ *
+ * The returned value is not guaranteed to be exact, but can be used as a
+ * general indicator of how "busy" the queue is.
+ *
+ * Invalid queue handles or handles to free/destroyed queues leads to
+ * undefined behaviour.
+ *
+ * @param queue Queue handle
+ *
+ * @retval Number of events currently in the queue.
+ */
+int odp_queue_depth(odp_queue_t queue);
+
+/**
* @}
*/
@@ -75,6 +75,8 @@ struct queue_entry_s {
odp_pktin_queue_t pktin;
odp_pktout_queue_t pktout;
char name[ODP_QUEUE_NAME_LEN];
+
+ int depth;
};
union queue_entry_u {
@@ -33,6 +33,7 @@
#include <string.h>
#include <inttypes.h>
+#include <unistd.h>
typedef struct queue_table_t {
queue_entry_t queue[ODP_CONFIG_QUEUES];
@@ -99,6 +100,8 @@ static int queue_init(queue_entry_t *queue, const char *name,
queue->s.head = NULL;
queue->s.tail = NULL;
+ queue->s.depth = 0;
+
return 0;
}
@@ -443,6 +446,7 @@ static inline int enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
queue->s.tail->next = hdr;
queue->s.tail = tail;
+ queue->s.depth += num;
if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
queue->s.status = QUEUE_STATUS_SCHED;
@@ -498,6 +502,7 @@ int odp_queue_enq(odp_queue_t handle, odp_event_t ev)
queue_entry_t *queue;
queue = queue_to_qentry(handle);
+
buf_hdr = buf_hdl_to_hdr(odp_buffer_from_event(ev));
return queue->s.enqueue(queue, buf_hdr);
@@ -560,8 +565,11 @@ static inline int deq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[],
}
/* Write head only if updated */
- if (updated)
+ if (updated) {
queue->s.head = hdr;
+ ODP_ASSERT(queue->s.depth >= (uint64_t)i);
+ queue->s.depth -= i;
+ }
/* Queue is empty */
if (hdr == NULL)
@@ -761,3 +769,23 @@ int sched_cb_queue_empty(uint32_t queue_index)
return ret;
}
+
+int odp_queue_depth(odp_queue_t handle)
+{
+ uint32_t queue_id;
+ queue_entry_t *queue;
+ int depth;
+
+ queue_id = queue_to_id(handle);
+
+ if (odp_unlikely(queue_id >= ODP_CONFIG_QUEUES)) {
+ ODP_ERR("Invalid queue handle:%" PRIu64 "\n",
+ odp_queue_to_u64(handle));
+ return 0;
+ }
+
+ queue = get_qentry(queue_id);
+ depth = queue->s.depth;
+
+ return depth;
+}
@@ -216,6 +216,8 @@ void queue_test_param(void)
* But here we assume that we succeed in enqueuing all buffers.
*/
ret = odp_queue_enq_multi(queue, enev, MAX_BUFFER_QUEUE);
+ int depth = odp_queue_depth(queue);
+ CU_ASSERT_EQUAL(depth, MAX_BUFFER_QUEUE);
CU_ASSERT(MAX_BUFFER_QUEUE == ret);
i = ret < 0 ? 0 : ret;
for ( ; i < MAX_BUFFER_QUEUE; i++)
- Added a counter to queue_entry_t to keep track of the current queue depth (number of enqueued events). - Added odp_queue_depth function to the API to query the above counter. Signed-off-by: Sergei Trofimov <sergei.trofimov@arm.com> --- include/odp/api/spec/queue.h | 15 +++++++++++ .../linux-generic/include/odp_queue_internal.h | 2 ++ platform/linux-generic/odp_queue.c | 30 +++++++++++++++++++++- test/common_plat/validation/api/queue/queue.c | 2 ++ 4 files changed, 48 insertions(+), 1 deletion(-) -- 1.9.1