Optional feature to get the max level that has ever been held by a queue (#444)

I'm using this in my program to get a better idea of how many entries I
need to allocate to avoid blocking or losing data, and to debug performance
issues.
This commit is contained in:
Jonathan Reichelt Gjertsen 2021-05-24 23:31:30 +02:00 committed by GitHub
parent 596d08ea62
commit 060123dc8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 0 deletions

View File

@ -10,6 +10,11 @@
#include "pico.h" #include "pico.h"
#include "hardware/sync.h" #include "hardware/sync.h"
// PICO_CONFIG: PICO_QUEUE_MAX_LEVEL, Maintain a field for the highest level that has been reached by a queue, type=bool, default=0, advanced=true, group=queue
#ifndef PICO_QUEUE_MAX_LEVEL
#define PICO_QUEUE_MAX_LEVEL 0
#endif
/** \file queue.h /** \file queue.h
* \defgroup queue queue * \defgroup queue queue
* Multi-core and IRQ safe queue implementation. * Multi-core and IRQ safe queue implementation.
@ -31,6 +36,9 @@ typedef struct {
uint16_t rptr; uint16_t rptr;
uint16_t element_size; uint16_t element_size;
uint16_t element_count; uint16_t element_count;
#if PICO_QUEUE_MAX_LEVEL
uint16_t max_level;
#endif
} queue_t; } queue_t;
/*! \brief Initialise a queue with a specific spinlock for concurrency protection /*! \brief Initialise a queue with a specific spinlock for concurrency protection
@ -93,6 +101,32 @@ static inline uint queue_get_level(queue_t *q) {
return level; return level;
} }
/*! \brief Returns the highest level reached by the specified queue since it was created
* or since the max level was reset
* \ingroup queue
*
* \param q Pointer to a queue_t structure, used as a handle
* \return Maximum level of the queue
*/
#if PICO_QUEUE_MAX_LEVEL
static inline uint queue_get_max_level(queue_t *q) {
return q->max_level;
}
#endif
/*! \brief Reset the highest level reached of the specified queue.
* \ingroup queue
*
* \param q Pointer to a queue_t structure, used as a handle
*/
#if PICO_QUEUE_MAX_LEVEL
static inline void queue_reset_max_level(queue_t *q) {
uint32_t save = spin_lock_blocking(q->core.spin_lock);
q->max_level = queue_get_level_unsafe(q);
spin_unlock(q->core.spin_lock, save);
}
#endif
/*! \brief Check if queue is empty /*! \brief Check if queue is empty
* \ingroup queue * \ingroup queue
* *

View File

@ -30,6 +30,14 @@ static inline uint16_t inc_index(queue_t *q, uint16_t index) {
if (++index > q->element_count) { // > because we have element_count + 1 elements if (++index > q->element_count) { // > because we have element_count + 1 elements
index = 0; index = 0;
} }
#if PICO_QUEUE_MAX_LEVEL
uint16_t level = queue_get_level_unsafe(q);
if (level > q->max_level) {
q->max_level = level;
}
#endif
return index; return index;
} }