diff --git a/subsys/logging/log_core.c b/subsys/logging/log_core.c index 29dddcfc9b2..ba6918601ba 100644 --- a/subsys/logging/log_core.c +++ b/subsys/logging/log_core.c @@ -17,14 +17,13 @@ #define CONFIG_LOG_PRINTK_MAX_STRING_LENGTH 1 #endif -#define LOG_STRBUF_STR_SIZE \ - (CONFIG_LOG_STRDUP_MAX_STRING + 1) /* additional byte for termination */ - -#define LOG_STRBUF_BUF_SIZE \ - ROUND_UP(LOG_STRBUF_STR_SIZE + sizeof(u32_t), sizeof(u32_t)) +struct log_strdup_buf { + atomic_t refcount; + char buf[CONFIG_LOG_STRDUP_MAX_STRING + 1]; /* for termination */ +}; #define LOG_STRDUP_POOL_BUFFER_SIZE \ - (LOG_STRBUF_BUF_SIZE * CONFIG_LOG_STRDUP_BUF_COUNT) + (sizeof(struct log_strdup_buf) * CONFIG_LOG_STRDUP_BUF_COUNT) static const char *log_strdup_fail_msg = "log_strdup pool empty!"; struct k_mem_slab log_strdup_pool; @@ -258,7 +257,7 @@ void log_init(void) } k_mem_slab_init(&log_strdup_pool, log_strdup_pool_buf, - LOG_STRBUF_BUF_SIZE, + sizeof(struct log_strdup_buf), CONFIG_LOG_STRDUP_BUF_COUNT); /* Set default timestamp. */ @@ -510,51 +509,43 @@ u32_t log_filter_get(struct log_backend const *const backend, char *log_strdup(const char *str) { - u32_t *dupl; - char *sdupl; + struct log_strdup_buf *dup; int err; - err = k_mem_slab_alloc(&log_strdup_pool, (void **)&dupl, K_NO_WAIT); + err = k_mem_slab_alloc(&log_strdup_pool, (void **)&dup, K_NO_WAIT); if (err) { /* failed to allocate */ return (char *)log_strdup_fail_msg; } /* Set 'allocated' flag. */ - *dupl = 1; - dupl++; - sdupl = (char *)dupl; + atomic_set(&dup->refcount, 1); - strncpy(sdupl, str, CONFIG_LOG_STRDUP_MAX_STRING - 1); - sdupl[LOG_STRBUF_STR_SIZE - 1] = '\0'; - sdupl[LOG_STRBUF_STR_SIZE - 2] = '~'; + strncpy(dup->buf, str, sizeof(dup->buf) - 2); + dup->buf[sizeof(dup->buf) - 2] = '~'; + dup->buf[sizeof(dup->buf) - 1] = '\0'; - return sdupl; + return dup->buf; } bool log_is_strdup(void *buf) { - /* Lowest possible address is located at the second word of the first - * buffer in the pool. First word is dedicated for 'allocated' flag. - * - * Highest possible address is the second word of the last buffer in the - * pool. - */ - static const void *start = log_strdup_pool_buf + sizeof(u32_t); - static const void *end = &log_strdup_pool_buf[ - LOG_STRDUP_POOL_BUFFER_SIZE - - LOG_STRBUF_BUF_SIZE - + sizeof(u32_t)]; - return (buf >= start) && (buf <= end); + struct log_strdup_buf *pool_first, *pool_last; + + pool_first = (struct log_strdup_buf *)log_strdup_pool_buf; + pool_last = pool_first + CONFIG_LOG_STRDUP_BUF_COUNT - 1; + + return ((char *)buf >= pool_first->buf) && + ((char *)buf <= pool_last->buf); } void log_free(void *str) { - u32_t *buf = (u32_t *)str; + struct log_strdup_buf *dup = CONTAINER_OF(str, struct log_strdup_buf, + buf); - buf--; - if (atomic_dec((atomic_t *)buf) == 1) { - k_mem_slab_free(&log_strdup_pool, (void **)&buf); + if (atomic_dec(&dup->refcount) == 1) { + k_mem_slab_free(&log_strdup_pool, (void **)&dup); } }