Update cache when changing log levels so change is effective

If any log messages with a particular tag string had already been
output before the call was made to adjust the logging level then the
new setting would not take effect because the level was cached.

This change updates the cached level to the new value and also finds
and updates the existing entry in the full uncached list rather than
adding a new entry to the end of the list.
This commit is contained in:
Stephen Casner 2017-12-09 18:42:50 -08:00
parent 5ae2c0d0ff
commit e4c0a39723

View file

@ -96,6 +96,7 @@ static uint32_t s_log_cache_misses = 0;
static inline bool get_cached_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);
static inline bool update_cached_log_level(const char* tag, esp_log_level_t level);
static inline void add_to_cache(const char* tag, esp_log_level_t level);
static void heap_bubble_down(int index);
static inline void heap_swap(int i, int j);
@ -121,8 +122,20 @@ void esp_log_level_set(const char* tag, esp_log_level_t level)
xSemaphoreGive(s_log_mutex);
return;
}
// otherwise update the cached entry if it exists
update_cached_log_level(tag, level);
// allocate new linked list entry and append it to the endo of the list
// Walk the linked list of all tags and see if given tag is present in the list.
// If so, update it. This is slow because tags are compared as strings.
for (uncached_tag_entry_t* it = s_log_tags_head; it != NULL; it = it->next) {
if (strcmp(tag, it->tag) == 0) {
it->level = level;
xSemaphoreGive(s_log_mutex);
return;
}
}
// allocate new linked list entry and append it to the end of the list
size_t entry_size = offsetof(uncached_tag_entry_t, tag) + strlen(tag) + 1;
uncached_tag_entry_t* new_entry = (uncached_tag_entry_t*) malloc(entry_size);
if (!new_entry) {
@ -222,6 +235,37 @@ static inline bool get_cached_log_level(const char* tag, esp_log_level_t* level)
return true;
}
static inline bool update_cached_log_level(const char* tag, esp_log_level_t level)
{
// Look for `tag` in cache
int i;
for (i = 0; i < s_log_cache_entry_count; ++i) {
#ifdef LOG_BUILTIN_CHECKS
assert(i == 0 || s_log_cache[(i - 1) / 2].generation < s_log_cache[i].generation);
#endif
if (strcmp(s_log_cache[i].tag, tag) == 0) {
break;
}
}
if (i == s_log_cache_entry_count) { // Not found in cache
return false;
}
// Set new level from cache
s_log_cache[i].level = level;
// If cache has been filled, start taking ordering into account
// (other options are: dynamically resize cache, add "dummy" entries
// to the cache; this option was chosen because code is much simpler,
// and the unfair behavior of cache will show it self at most once, when
// it has just been filled)
if (s_log_cache_entry_count == TAG_CACHE_SIZE) {
// Update item generation
s_log_cache[i].generation = s_log_cache_max_generation++;
// Restore heap ordering
heap_bubble_down(i);
}
return true;
}
static inline void add_to_cache(const char* tag, esp_log_level_t level)
{
uint32_t generation = s_log_cache_max_generation++;