From 28c4ba1288f6e61fc103ce3e37cf09278bd13801 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 24 Aug 2017 16:53:16 +0800 Subject: [PATCH 1/3] doc(log): document the log macros. --- components/log/include/esp_log.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/components/log/include/esp_log.h b/components/log/include/esp_log.h index b3918a93ff..734c80fe78 100644 --- a/components/log/include/esp_log.h +++ b/components/log/include/esp_log.h @@ -154,10 +154,15 @@ void esp_log_buffer_char(const char *tag, const void *buffer, uint16_t buff_len) #endif #endif +/// macro to output logs in startup code, before heap allocator and syscalls have been initialized. log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE`` #define ESP_EARLY_LOGE( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { ets_printf(LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } +/// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` #define ESP_EARLY_LOGW( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { ets_printf(LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } +/// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` #define ESP_EARLY_LOGI( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { ets_printf(LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } +/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` #define ESP_EARLY_LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } +/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` #define ESP_EARLY_LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { ets_printf(LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } #ifndef BOOTLOADER_BUILD @@ -167,10 +172,21 @@ void esp_log_buffer_char(const char *tag, const void *buffer, uint16_t buff_len) #define ESP_LOGD( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } #define ESP_LOGV( tag, format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } #else +/** + * macro to output logs at ESP_LOG_ERROR level. + * + * @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime. + * + * @see ``printf`` + */ #define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__) +/// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE`` #define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__) +/// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE`` #define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__) +/// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE`` #define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__) +/// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE`` #define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__) #endif // BOOTLOADER_BUILD From 940f5fcb89168f910f3356525b4fce11c36065c1 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 24 Aug 2017 20:09:51 +0800 Subject: [PATCH 2/3] refactor(log): replace the tag uncached list with standard SLIST. NOTE: split the header modify outside. --- components/log/log.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/components/log/log.c b/components/log/log.c index 6a9756a24e..07f8135a41 100644 --- a/components/log/log.c +++ b/components/log/log.c @@ -13,7 +13,7 @@ // limitations under the License. /* - * Log library — implementation notes. + * Log library â€implementation notes. * * Log library stores all tags provided to esp_log_level_set as a linked * list. See uncached_tag_entry_t structure. @@ -53,6 +53,7 @@ #include #include #include "esp_log.h" +#include "rom/queue.h" //print number of bytes per line for esp_log_buffer_char and esp_log_buffer_hex #define BYTES_PER_LINE 16 @@ -76,14 +77,13 @@ typedef struct { } cached_tag_entry_t; typedef struct uncached_tag_entry_{ - struct uncached_tag_entry_* next; + SLIST_ENTRY(uncached_tag_entry_) entries; uint8_t level; // esp_log_level_t as uint8_t char tag[0]; // beginning of a zero-terminated string } uncached_tag_entry_t; static esp_log_level_t s_log_default_level = ESP_LOG_VERBOSE; -static uncached_tag_entry_t* s_log_tags_head = NULL; -static uncached_tag_entry_t* s_log_tags_tail = NULL; +static SLIST_HEAD(log_tags_head , uncached_tag_entry_) s_log_tags = SLIST_HEAD_INITIALIZER(s_log_tags); static cached_tag_entry_t s_log_cache[TAG_CACHE_SIZE]; static uint32_t s_log_cache_max_generation = 0; static uint32_t s_log_cache_entry_count = 0; @@ -122,41 +122,29 @@ void esp_log_level_set(const char* tag, esp_log_level_t level) return; } - // allocate new linked list entry and append it to the endo of the list + // allocate new linked list entry and append it to the head 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) { xSemaphoreGive(s_log_mutex); return; } - new_entry->next = NULL; new_entry->level = (uint8_t) level; strcpy(new_entry->tag, tag); - if (s_log_tags_tail) { - s_log_tags_tail->next = new_entry; - } - s_log_tags_tail = new_entry; - if (!s_log_tags_head) { - s_log_tags_head = new_entry; - } + SLIST_INSERT_HEAD( &s_log_tags, new_entry, entries ); xSemaphoreGive(s_log_mutex); } void clear_log_level_list() { - for (uncached_tag_entry_t* it = s_log_tags_head; it != NULL; ) { - uncached_tag_entry_t* next = it->next; - free(it); - it = next; + while( !SLIST_EMPTY(&s_log_tags)) { + SLIST_REMOVE_HEAD(&s_log_tags, entries ); } - s_log_tags_tail = NULL; - s_log_tags_head = NULL; s_log_cache_entry_count = 0; s_log_cache_max_generation = 0; #ifdef LOG_BUILTIN_CHECKS s_log_cache_misses = 0; #endif - } void IRAM_ATTR esp_log_write(esp_log_level_t level, @@ -253,7 +241,8 @@ static inline bool get_uncached_log_level(const char* tag, esp_log_level_t* leve { // Walk the linked list of all tags and see if given tag is present in the list. // This is slow because tags are compared as strings. - for (uncached_tag_entry_t* it = s_log_tags_head; it != NULL; it = it->next) { + uncached_tag_entry_t *it; + SLIST_FOREACH( it, &s_log_tags, entries ) { if (strcmp(tag, it->tag) == 0) { *level = it->level; return true; From cfd95b62cb846a62641bccf420dd2ffc1b6262aa Mon Sep 17 00:00:00 2001 From: michael Date: Fri, 25 Aug 2017 11:46:55 +0800 Subject: [PATCH 3/3] feat(log): add tags only when no one exist, otherwise refresh linked list and cache. --- components/log/log.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/components/log/log.c b/components/log/log.c index 07f8135a41..33ebc2da41 100644 --- a/components/log/log.c +++ b/components/log/log.c @@ -13,7 +13,7 @@ // limitations under the License. /* - * Log library â€implementation notes. + * Log library implementation notes. * * Log library stores all tags provided to esp_log_level_set as a linked * list. See uncached_tag_entry_t structure. @@ -122,16 +122,40 @@ void esp_log_level_set(const char* tag, esp_log_level_t level) return; } - // allocate new linked list entry and append it to the head 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) { - xSemaphoreGive(s_log_mutex); - return; + //searching exist tag + uncached_tag_entry_t *it = NULL; + SLIST_FOREACH( it, &s_log_tags, entries ) { + if ( strcmp(it->tag, tag)==0 ) { + //one tag in the linked list match, update the level + it->level = level; + //quit with it != NULL + break; + } + } + //no exist tag, append new one + if ( it == NULL ) { + // allocate new linked list entry and append it to the head 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) { + xSemaphoreGive(s_log_mutex); + return; + } + new_entry->level = (uint8_t) level; + strcpy(new_entry->tag, tag); + SLIST_INSERT_HEAD( &s_log_tags, new_entry, entries ); + } + + //search in the cache and update it if exist + for (int 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 (s_log_cache[i].tag == tag) { + s_log_cache[i].level = level; + break; + } } - new_entry->level = (uint8_t) level; - strcpy(new_entry->tag, tag); - SLIST_INSERT_HEAD( &s_log_tags, new_entry, entries ); xSemaphoreGive(s_log_mutex); }