Ensure the timestamp always increases in zero-copy libdlog 01/283301/2
authorMateusz Majewski <m.majewski2@samsung.com>
Fri, 21 Oct 2022 13:08:12 +0000 (15:08 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Mon, 24 Oct 2022 06:03:53 +0000 (08:03 +0200)
The kernel guarantees that it won't decrease, but if function is
executed in quick repetition it might happen that we get the same value
twice in a row. This is unacceptable, since the timestamp is the only
thing we rely on in order to sort the messages.

This mirrors a similar change in the kernel module, see 282866. In the
kernel the issue has been more visible since the kernel might split the
messages in a quite arbitrary way. In userspace the issue has been
harder to notice, but with Marek's changes increasing the performance it
has become more urgent.

Change-Id: I993529a2f8e7f8e477733c929232b10fb981eaba

src/libdlog/log_zero_copy.c

index 080afbd..3ad04ae 100644 (file)
@@ -40,6 +40,7 @@
 static int g_fd = 0;
 _Thread_local volatile void *g_shm_ptr = 0;
 _Thread_local int g_tid = 0;
+_Thread_local uint64_t last_ts = 0;
 
 extern int (*write_to_log)(log_id_t log_id, log_priority prio, const char *tag, const char *msg, struct timespec *tp_mono);
 extern void (*destroy_backend)(void);
@@ -113,6 +114,14 @@ static int zero_copy_write(log_id_t log_id, log_priority prio, const char *tag,
        if ((char *)entry + entry_size > (char *)block + ZLOGGER_BLOCK_SIZE)
                return -1;
 
+       /* Ensure that the timestamp is increasing, as opposed to
+        * merely not decreasing. This is done to make sure that
+        * logs can be sorted (which can be ambiguous if there are
+        * multiple valid logs with the same timestamp). */
+       if (last_ts >= ts)
+               ts = last_ts + 1;
+       last_ts = ts;
+
        uint16_t *slt = (uint16_t *)&ts;
        struct zlogger_entry tmp = {ts, slt[0] + slt[1] + slt[2] + slt[3], (uint16_t)entry_size - hd_size};
        memcpy(entry, &tmp, hd_size);