[PATCH] erofs-utils: lib: introduce atomic operations

Yifan Zhao zhaoyifan at sjtu.edu.cn
Thu Feb 29 00:22:48 AEDT 2024


On 2/28/24 16:21, Gao Xiang wrote:
> 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<zhaoyifan at sjtu.edu.cn>
> Signed-off-by: Gao Xiang<hsiangkao at linux.alibaba.com>
> ---
>   include/erofs/atomic.h      | 27 +++++++++++++++++++++++++++
>   lib/compressor_deflate.c    | 11 ++++++++---
>   lib/compressor_libdeflate.c |  6 +++++-
>   lib/compressor_liblzma.c    |  5 ++++-
>   4 files changed, 44 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..c486491
> --- /dev/null
> +++ b/include/erofs/atomic.h
> @@ -0,0 +1,27 @@
> +/* 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;

According to [1] *__atomic_test_and_set *should**only be used for 
operands of type bool or char.

[1] https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html

Maybe add

/typedef bool erofs_atomic_bool_t;
/

for this purpose?

Otherwise LGTM and I will include it in my patchset.


Thanks,

Yifan Zhao

> +
> +#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..60bb2f6 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_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 at 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 at lists.ozlabs.org>  if something is wrong.");
> +	}
>   	return 0;
>   }
>   
> diff --git a/lib/compressor_libdeflate.c b/lib/compressor_libdeflate.c
> index 62d93f7..f90d720 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_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..e79717d 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_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;
>   }
>   
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linux-erofs/attachments/20240228/bc167bb4/attachment.htm>


More information about the Linux-erofs mailing list