#include <unistd.h>
#include <pthread.h>
+#include <libdlog.h>
#include <logcommon.h>
#include <zero_copy_backend.h>
-static int g_fd;
-static char *g_shm_ptr[ZLOGGER_DEVICE_COUNT];
-_Thread_local uint16_t blk = 0;
+static int g_fd = 0;
+_Thread_local volatile void *g_shm_ptr = 0;
_Thread_local int g_tid = 0;
extern int (*write_to_log)(log_id_t log_id, log_priority prio, const char *tag, const char *msg, struct timespec *tp_mono);
static void clear_thread_locals(void)
{
g_tid = 0;
+ g_shm_ptr = 0;
}
-static inline char *get_shared_memory(int dev_index)
+static volatile struct zlogger_block *get_valid_block(int tid, size_t len)
{
- if (dev_index < 0 || dev_index >= ZLOGGER_DEVICE_COUNT)
- return NULL;
-
- return g_shm_ptr[dev_index];
-}
+ if (g_shm_ptr == 0) {
+ void *ptr = mmap(NULL, ZLOGGER_BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
-static inline struct zlogger_block *get_block(uint16_t block_index)
-{
- uint16_t index = block_index - 1;
- int offset = index & (ZLOGGER_BLOCK_MAP_COUNT - 1);
- char *p = get_shared_memory(index / ZLOGGER_BLOCK_MAP_COUNT);
-
- if (!p)
- return NULL;
+ if (ptr == MAP_FAILED)
+ return NULL;
- return (struct zlogger_block *)(p + (offset * ZLOGGER_BLOCK_SIZE));
-}
-
-static inline int alloc_block(int tid)
-{
- int r = ioctl(g_fd, ZLOGGER_IOCTL_COMMAND_ALLOC, 0);
- return r;
-}
+ g_shm_ptr = ptr;
+ }
-static inline struct zlogger_block *get_valid_block(int tid, size_t len)
-{
- if (blk != 0) {
- struct zlogger_block *block = get_block(blk);
+ volatile struct zlogger_block *block = (struct zlogger_block *)g_shm_ptr;
- if (block && block->head.tid == tid && block->head.offset + len < ZLOGGER_DATA_MAX)
- return block;
- }
+ if (block->head.tid == tid && block->head.offset + len < ZLOGGER_DATA_MAX)
+ return block;
- int r = alloc_block(tid);
- if (r <= 0)
+ /* Ask kernel to remap mmapped g_shm_ptr to the new memory block */
+ if (ioctl(g_fd, ZLOGGER_IOCTL_COMMAND_ALLOC, 0) < 0)
return NULL;
- blk = r;
- return get_block((uint16_t)r);
+ if (block->head.tid == tid && block->head.offset + len < ZLOGGER_DATA_MAX)
+ return block;
+
+ return NULL;
}
static int zero_copy_write(log_id_t log_id, log_priority prio, const char *tag, const char *msg, struct timespec *tp_mono)
size_t tag_size = strnlen(tag, ZLOGGER_TAG_MAX) + 1;
size_t msg_size = strnlen(msg, ZLOGGER_MSG_MAX) + 1;
size_t entry_size = hd_size + prio_size + tag_size + msg_size;
- struct zlogger_block *block = get_valid_block(tid, entry_size);
+ volatile struct zlogger_block *block = get_valid_block(tid, entry_size);
if (block == NULL)
return -1;
block->head.offset += (uint16_t)entry_size;
block->head.ts = ts;
- return 0;
+ return msg_size;
}
static void zero_copy_deinit(void)
{
- for (int i = 0; i < ZLOGGER_DEVICE_COUNT; i++) {
- if (g_shm_ptr[i] == MAP_FAILED)
- continue;
-
- munmap(g_shm_ptr[i], ZLOGGER_MAP_SIZE);
- g_shm_ptr[i] = MAP_FAILED;
- }
-
if (g_fd > 0) {
close(g_fd);
g_fd = -1;
}
}
-struct log_config;
-int __dlog_init_zero_copy(struct log_config *config)
+int __dlog_init_zero_copy(const struct log_config *config)
{
- (void) config;
-
g_fd = open(ZERO_COPY_DEVICE_NAME, O_RDWR | O_CLOEXEC);
if (g_fd < 0)
return -1;
return -1;
}
- for (int i = 0; i < ZLOGGER_DEVICE_COUNT; i++)
- g_shm_ptr[i] = MAP_FAILED;
-
- for (int i = 0; i < ZLOGGER_DEVICE_COUNT; i++) {
- g_shm_ptr[i] = mmap(NULL, ZLOGGER_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, (ZLOGGER_MAP_SIZE * i));
- if (g_shm_ptr[i] == MAP_FAILED) {
- zero_copy_deinit();
- return -1;
- }
- }
-
write_to_log = zero_copy_write;
destroy_backend = zero_copy_deinit;