mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
fix(log): Fix wrap-around of cache generation counter
Closes https://github.com/espressif/esp-idf/issues/6516
This commit is contained in:
parent
46976bdcb7
commit
1e7830e57b
@ -21,11 +21,6 @@
|
|||||||
* After that, bubble-down operation is performed to fix ordering in the
|
* After that, bubble-down operation is performed to fix ordering in the
|
||||||
* min-heap.
|
* min-heap.
|
||||||
*
|
*
|
||||||
* The potential problem with wrap-around of cache generation counter is
|
|
||||||
* ignored for now. This will happen if someone happens to output more
|
|
||||||
* than 4 billion log entries, at which point wrap-around will not be
|
|
||||||
* the biggest problem.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -49,11 +44,12 @@
|
|||||||
|
|
||||||
// Number of tags to be cached. Must be 2**n - 1, n >= 2.
|
// Number of tags to be cached. Must be 2**n - 1, n >= 2.
|
||||||
#define TAG_CACHE_SIZE 31
|
#define TAG_CACHE_SIZE 31
|
||||||
|
#define MAX_GENERATION ((1 << 29) - 1)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *tag;
|
const char *tag;
|
||||||
uint32_t level : 3;
|
uint32_t level : 3;
|
||||||
uint32_t generation : 29;
|
uint32_t generation : 29; // this size should be the same in MAX_GENERATION
|
||||||
} cached_tag_entry_t;
|
} cached_tag_entry_t;
|
||||||
|
|
||||||
typedef struct uncached_tag_entry_ {
|
typedef struct uncached_tag_entry_ {
|
||||||
@ -81,6 +77,7 @@ static void heap_bubble_down(int index);
|
|||||||
static inline void heap_swap(int i, int j);
|
static inline void heap_swap(int i, int j);
|
||||||
static inline bool should_output(esp_log_level_t level_for_message, esp_log_level_t level_for_tag);
|
static inline bool should_output(esp_log_level_t level_for_message, esp_log_level_t level_for_tag);
|
||||||
static inline void clear_log_level_list(void);
|
static inline void clear_log_level_list(void);
|
||||||
|
static void fix_cache_generation_overflow(void);
|
||||||
|
|
||||||
vprintf_like_t esp_log_set_vprintf(vprintf_like_t func)
|
vprintf_like_t esp_log_set_vprintf(vprintf_like_t func)
|
||||||
{
|
{
|
||||||
@ -238,6 +235,10 @@ static inline bool get_cached_log_level(const char *tag, esp_log_level_t *level)
|
|||||||
s_log_cache[i].generation = s_log_cache_max_generation++;
|
s_log_cache[i].generation = s_log_cache_max_generation++;
|
||||||
// Restore heap ordering
|
// Restore heap ordering
|
||||||
heap_bubble_down(i);
|
heap_bubble_down(i);
|
||||||
|
// Check for generation count wrap and fix if necessary
|
||||||
|
if (s_log_cache_max_generation == MAX_GENERATION) {
|
||||||
|
fix_cache_generation_overflow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -255,18 +256,30 @@ static inline void add_to_cache(const char *tag, esp_log_level_t level)
|
|||||||
.tag = tag
|
.tag = tag
|
||||||
};
|
};
|
||||||
++s_log_cache_entry_count;
|
++s_log_cache_entry_count;
|
||||||
return;
|
} else {
|
||||||
|
// Cache is full, so we replace the oldest entry (which is at index 0
|
||||||
|
// because this is a min-heap) with the new one, and do bubble-down
|
||||||
|
// operation to restore min-heap ordering.
|
||||||
|
s_log_cache[0] = (cached_tag_entry_t) {
|
||||||
|
.tag = tag,
|
||||||
|
.level = level,
|
||||||
|
.generation = generation
|
||||||
|
};
|
||||||
|
heap_bubble_down(0);
|
||||||
}
|
}
|
||||||
|
// Check for generation count wrap and fix if necessary
|
||||||
|
if (s_log_cache_max_generation == MAX_GENERATION) {
|
||||||
|
fix_cache_generation_overflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cache is full, so we replace the oldest entry (which is at index 0
|
static void fix_cache_generation_overflow(void)
|
||||||
// because this is a min-heap) with the new one, and do bubble-down
|
{
|
||||||
// operation to restore min-heap ordering.
|
// Fix generation count wrap
|
||||||
s_log_cache[0] = (cached_tag_entry_t) {
|
for (uint32_t i = 0; i < s_log_cache_entry_count; ++i) {
|
||||||
.tag = tag,
|
s_log_cache[i].generation = i;
|
||||||
.level = level,
|
}
|
||||||
.generation = generation
|
s_log_cache_max_generation = s_log_cache_entry_count;
|
||||||
};
|
|
||||||
heap_bubble_down(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool get_uncached_log_level(const char *tag, esp_log_level_t *level)
|
static inline bool get_uncached_log_level(const char *tag, esp_log_level_t *level)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user