diff --git a/src/common/pico_util/include/pico/util/queue.h b/src/common/pico_util/include/pico/util/queue.h index e83ecd4..6fba9af 100644 --- a/src/common/pico_util/include/pico/util/queue.h +++ b/src/common/pico_util/include/pico/util/queue.h @@ -10,6 +10,11 @@ #include "pico.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 * \defgroup queue queue * Multi-core and IRQ safe queue implementation. @@ -31,6 +36,9 @@ typedef struct { uint16_t rptr; uint16_t element_size; uint16_t element_count; +#if PICO_QUEUE_MAX_LEVEL + uint16_t max_level; +#endif } queue_t; /*! \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; } +/*! \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 * \ingroup queue * diff --git a/src/common/pico_util/queue.c b/src/common/pico_util/queue.c index bc667ac..8e9866d 100644 --- a/src/common/pico_util/queue.c +++ b/src/common/pico_util/queue.c @@ -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 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; }