mirror of
https://github.com/tezc/sc.git
synced 2025-01-28 07:03:06 +08:00
atomic log level read
This commit is contained in:
parent
8eff74a4f4
commit
4ac9d8691b
@ -1,6 +1,6 @@
|
|||||||
### Overview
|
### Overview
|
||||||
|
|
||||||
Common data structures utilities for C.
|
Common data structures and utilities for C.
|
||||||
|
|
||||||
Each folder is independent and contains a header and a source file.
|
Each folder is independent and contains a header and a source file.
|
||||||
There is no build for libraries, just copy *.h *.c files into your project.
|
There is no build for libraries, just copy *.h *.c files into your project.
|
||||||
@ -37,6 +37,8 @@ CI runs on Linux, MacOS, FreeBSD and Windows with gcc, clang and msvc.
|
|||||||
| **[uri](uri)** | A basic uri parser |
|
| **[uri](uri)** | A basic uri parser |
|
||||||
|
|
||||||
### Test
|
### Test
|
||||||
|
[![codecov](https://codecov.io/gh/tezc/sc/branch/master/graph/badge.svg?token=O8ZHQ0XZ30)](https://codecov.io/gh/tezc/sc)
|
||||||
|
|
||||||
|
|
||||||
Although I use on Linux mostly, CI runs with
|
Although I use on Linux mostly, CI runs with
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ cmake .. -DSANITIZER=address && make && make check
|
|||||||
mkdir build; cd build;
|
mkdir build; cd build;
|
||||||
cmake .. -DSANITIZER=undefined && make && make check
|
cmake .. -DSANITIZER=undefined && make && make check
|
||||||
|
|
||||||
#coverage
|
#coverage, requires GCC.
|
||||||
mkdir build; cd build;
|
mkdir build; cd build;
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Coverage; make; make coverage
|
cmake .. -DCMAKE_BUILD_TYPE=Coverage; make; make coverage
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
- Log destination can be stdout, file and user callback.
|
- Log destination can be stdout, file and user callback.
|
||||||
- You can pass logs to all destinations at the same time.
|
- You can pass logs to all destinations at the same time.
|
||||||
- Log files are rotated.
|
- Log files are rotated.
|
||||||
- Thread-safe.
|
- Thread-safe, requires pthread.
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
|
@ -43,8 +43,22 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_local char sc_name[32] = "Thread";
|
#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_ATOMIC__
|
||||||
|
#define SC_ATOMIC
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
|
#define sc_atomic _Atomic
|
||||||
|
#define sc_atomic_store(var, val) \
|
||||||
|
(atomic_store_explicit(var, val, memory_order_relaxed))
|
||||||
|
#define sc_atomic_load(var) \
|
||||||
|
(atomic_load_explicit(var, memory_order_relaxed))
|
||||||
|
#else
|
||||||
|
#define sc_atomic
|
||||||
|
#define sc_atomic_store(var, val) ((*(var)) = (val))
|
||||||
|
#define sc_atomic_load(var) (*(var))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
thread_local char sc_name[32] = "Thread";
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
@ -135,7 +149,7 @@ struct sc_log
|
|||||||
size_t file_size;
|
size_t file_size;
|
||||||
|
|
||||||
struct sc_log_mutex mtx;
|
struct sc_log_mutex mtx;
|
||||||
enum sc_log_level level;
|
sc_atomic enum sc_log_level level;
|
||||||
|
|
||||||
bool to_stdout;
|
bool to_stdout;
|
||||||
|
|
||||||
@ -151,7 +165,7 @@ int sc_log_init(void)
|
|||||||
|
|
||||||
sc_log = (struct sc_log){0};
|
sc_log = (struct sc_log){0};
|
||||||
|
|
||||||
sc_log.level = SC_LOG_INFO;
|
sc_atomic_store(&sc_log.level, SC_LOG_INFO);
|
||||||
sc_log.to_stdout = true;
|
sc_log.to_stdout = true;
|
||||||
|
|
||||||
rc = sc_log_mutex_init(&sc_log.mtx);
|
rc = sc_log_mutex_init(&sc_log.mtx);
|
||||||
@ -200,14 +214,17 @@ static int sc_strcasecmp(const char *a, const char *b)
|
|||||||
|
|
||||||
int sc_log_set_level(const char *str)
|
int sc_log_set_level(const char *str)
|
||||||
{
|
{
|
||||||
size_t count = sizeof(sc_log_levels) / sizeof(struct sc_log_level_pair);
|
size_t count = sizeof(sc_log_levels) / sizeof(sc_log_levels[0]);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
if (sc_strcasecmp(str, sc_log_levels[i].str) == 0) {
|
if (sc_strcasecmp(str, sc_log_levels[i].str) == 0) {
|
||||||
|
#ifdef SC_ATOMIC
|
||||||
|
sc_atomic_store(&sc_log.level, sc_log_levels[i].id);
|
||||||
|
#else
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
sc_log_mutex_lock(&sc_log.mtx);
|
||||||
sc_log.level = sc_log_levels[i].id;
|
sc_log.level = sc_log_levels[i].id;
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
sc_log_mutex_unlock(&sc_log.mtx);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,12 +365,25 @@ int sc_log_log(enum sc_log_level level, const char *fmt, ...)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
va_list va;
|
va_list va;
|
||||||
|
|
||||||
|
// Use relaxed atomics to avoid locking cost, e.g DEBUG logs when
|
||||||
|
// level=INFO will get away without any synchronization on most platforms.
|
||||||
|
#ifdef SC_ATOMIC
|
||||||
|
enum sc_log_level curr;
|
||||||
|
|
||||||
|
curr = sc_atomic_load(&sc_log.level);
|
||||||
|
if (level < curr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
sc_log_mutex_lock(&sc_log.mtx);
|
||||||
|
|
||||||
|
#ifndef SC_ATOMIC
|
||||||
if (level < sc_log.level) {
|
if (level < sc_log.level) {
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
sc_log_mutex_unlock(&sc_log.mtx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sc_log.to_stdout) {
|
if (sc_log.to_stdout) {
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user