Add some helpers (relaxed semantics) in order to prepare for the
upcoming multi-threaded support.

For example, compressor may be initialized more than once in different
worker threads, resulting in noisy warnings.

This patch makes sure that each message will be printed only once by
adding `__warnonce` atomic booleans to each erofs_compressor_init().

Cc: Yifan Zhao <zhaoyi...@sjtu.edu.cn>
Signed-off-by: Yifan Zhao <zhaoyi...@sjtu.edu.cn>
Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com>
---
 include/erofs/atomic.h      | 28 ++++++++++++++++++++++++++++
 lib/compressor_deflate.c    | 11 ++++++++---
 lib/compressor_libdeflate.c |  6 +++++-
 lib/compressor_liblzma.c    |  5 ++++-
 4 files changed, 45 insertions(+), 5 deletions(-)
 create mode 100644 include/erofs/atomic.h

diff --git a/include/erofs/atomic.h b/include/erofs/atomic.h
new file mode 100644
index 0000000..214cdb1
--- /dev/null
+++ b/include/erofs/atomic.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
+/*
+ * Copyright (C) 2024 Alibaba Cloud
+ */
+#ifndef __EROFS_ATOMIC_H
+#define __EROFS_ATOMIC_H
+
+/*
+ * Just use GCC/clang built-in functions for now
+ * See: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
+ */
+typedef unsigned long erofs_atomic_t;
+typedef char erofs_atomic_bool_t;
+
+#define erofs_atomic_read(ptr) ({ \
+       typeof(*ptr) __n;    \
+       __atomic_load(ptr, &__n, __ATOMIC_RELAXED); \
+__n;})
+
+#define erofs_atomic_set(ptr, n) do { \
+       typeof(*ptr) __n = (n);    \
+       __atomic_store(ptr, &__n, __ATOMIC_RELAXED); \
+} while(0)
+
+#define erofs_atomic_test_and_set(ptr) \
+       __atomic_test_and_set(ptr, __ATOMIC_RELAXED)
+
+#endif
diff --git a/lib/compressor_deflate.c b/lib/compressor_deflate.c
index 8629415..e482224 100644
--- a/lib/compressor_deflate.c
+++ b/lib/compressor_deflate.c
@@ -7,6 +7,7 @@
 #include "erofs/print.h"
 #include "erofs/config.h"
 #include "compressor.h"
+#include "erofs/atomic.h"
 
 void *kite_deflate_init(int level, unsigned int dict_size);
 void kite_deflate_end(void *s);
@@ -36,6 +37,8 @@ static int compressor_deflate_exit(struct erofs_compress *c)
 
 static int compressor_deflate_init(struct erofs_compress *c)
 {
+       static erofs_atomic_bool_t __warnonce;
+
        if (c->private_data) {
                kite_deflate_end(c->private_data);
                c->private_data = NULL;
@@ -44,9 +47,11 @@ static int compressor_deflate_init(struct erofs_compress *c)
        if (IS_ERR_VALUE(c->private_data))
                return PTR_ERR(c->private_data);
 
-       erofs_warn("EXPERIMENTAL DEFLATE algorithm in use. Use at your own 
risk!");
-       erofs_warn("*Carefully* check filesystem data correctness to avoid 
corruption!");
-       erofs_warn("Please send a report to <linux-erofs@lists.ozlabs.org> if 
something is wrong.");
+       if (!erofs_atomic_test_and_set(&__warnonce)) {
+               erofs_warn("EXPERIMENTAL DEFLATE algorithm in use. Use at your 
own risk!");
+               erofs_warn("*Carefully* check filesystem data correctness to 
avoid corruption!");
+               erofs_warn("Please send a report to 
<linux-erofs@lists.ozlabs.org> if something is wrong.");
+       }
        return 0;
 }
 
diff --git a/lib/compressor_libdeflate.c b/lib/compressor_libdeflate.c
index 62d93f7..14cbce4 100644
--- a/lib/compressor_libdeflate.c
+++ b/lib/compressor_libdeflate.c
@@ -4,6 +4,7 @@
 #include "erofs/config.h"
 #include <libdeflate.h>
 #include "compressor.h"
+#include "erofs/atomic.h"
 
 static int libdeflate_compress_destsize(const struct erofs_compress *c,
                                        const void *src, unsigned int *srcsize,
@@ -82,12 +83,15 @@ static int compressor_libdeflate_exit(struct erofs_compress 
*c)
 
 static int compressor_libdeflate_init(struct erofs_compress *c)
 {
+       static erofs_atomic_bool_t __warnonce;
+
        libdeflate_free_compressor(c->private_data);
        c->private_data = libdeflate_alloc_compressor(c->compression_level);
        if (!c->private_data)
                return -ENOMEM;
 
-       erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at your own 
risk!");
+       if (!erofs_atomic_test_and_set(&__warnonce))
+               erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at 
your own risk!");
        return 0;
 }
 
diff --git a/lib/compressor_liblzma.c b/lib/compressor_liblzma.c
index 712f44f..2f19a93 100644
--- a/lib/compressor_liblzma.c
+++ b/lib/compressor_liblzma.c
@@ -9,6 +9,7 @@
 #include "erofs/config.h"
 #include "erofs/print.h"
 #include "erofs/internal.h"
+#include "erofs/atomic.h"
 #include "compressor.h"
 
 struct erofs_liblzma_context {
@@ -85,6 +86,7 @@ static int erofs_compressor_liblzma_init(struct 
erofs_compress *c)
 {
        struct erofs_liblzma_context *ctx;
        u32 preset;
+       static erofs_atomic_bool_t __warnonce;
 
        ctx = malloc(sizeof(*ctx));
        if (!ctx)
@@ -103,7 +105,8 @@ static int erofs_compressor_liblzma_init(struct 
erofs_compress *c)
        ctx->opt.dict_size = c->dict_size;
 
        c->private_data = ctx;
-       erofs_warn("It may take a longer time since MicroLZMA is still 
single-threaded for now.");
+       if (!erofs_atomic_test_and_set(&__warnonce))
+               erofs_warn("It may take a longer time since MicroLZMA is still 
single-threaded for now.");
        return 0;
 }
 
-- 
2.39.3

Reply via email to