subsys: logging: Using struct to manger log_strdup buffer.

log_strdup requested for a piece of memory, with the first 4 bytes as
the number of references and the next used to copy strings. In the
implementation of this function, the memory is managed by user and
is a little hard to understand.

Rewriting this part of code, using structure to manage the memory
requested, make it easier to understand.

Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
This commit is contained in:
qianfan Zhao 2018-10-26 19:07:31 +08:00 committed by Anas Nashif
parent 48f65c47f0
commit 02bd01e856

View File

@ -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);
}
}