On 2022/7/6 17:33, fanghao (A) wrote:
在 2022/7/5 15:48, Yang Shen 写道:
The 'wd_<alg>_init()' is designed as non-reentrant. So add a status to protect for this situation.
When 'wd_<alg>_init()' is called, it will read the status at first. If the status is WD_UNINIT, it will set status as WD_INITING and change status to WD_INIT if succeed or reduction status to WD_UNINIT if something is wrong. If the status is WD_INIT, it can return directly. If the status is WD_INITING, that meaning other thread is initializing, so it need to wait for the result.
以前是上层比如uadk_engine加锁和置标志来保证互斥和重入。 现在是这个接口语义变了,自身保证了线程安全和重入。 所以,建议增加对用户的使用改变描述。 对应接口文档也要刷新。
OK,我会同步更新一下wd_design.md。
Signed-off-by: Yang Shen shenyang39@huawei.com
include/wd_util.h | 38 ++++++++++++++++++++++++++++++++++++++ wd_aead.c | 33 ++++++++++++++++++++++----------- wd_cipher.c | 35 +++++++++++++++++++++++------------ wd_comp.c | 35 ++++++++++++++++++++++++----------- wd_dh.c | 34 ++++++++++++++++++++++------------ wd_digest.c | 33 ++++++++++++++++++++++----------- wd_ecc.c | 33 ++++++++++++++++++++++----------- wd_rsa.c | 33 ++++++++++++++++++++++----------- wd_util.c | 16 ++++++++++++++++ 9 files changed, 211 insertions(+), 79 deletions(-)
diff --git a/include/wd_util.h b/include/wd_util.h index 83a9684..4077bca 100644 --- a/include/wd_util.h +++ b/include/wd_util.h @@ -21,6 +21,12 @@ extern "C" { for (i = 0, config_numa = config->config_per_numa; \ i < config->numa_num; config_numa++, i++) +enum wd_status {
- WD_UNINIT,
- WD_INITING,
- WD_INIT,
+};
- struct wd_async_msg_pool { struct msg_pool *pools; __u32 pool_num;
@@ -356,6 +362,38 @@ int wd_handle_msg_sync(struct wd_msg_handle *msg_handle, handle_t ctx, */ int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched); +/**
- wd_alg_try_init() - Check the algorithm status and set it as
WD_INITING
if need initialization.
- @status: algorithm initialization status.
- Return true if need initialization and false if initialized,
otherwise will wait
- last initialization result.
- */
+bool wd_alg_try_init(enum wd_status *status);
+/**
- wd_alg_set_init() - Set the algorithm status as WD_INIT.
- @status: algorithm initialization status.
- */
+static inline void wd_alg_set_init(enum wd_status *status) +{
- enum wd_status setting = WD_INIT;
- __atomic_store(status, &setting, __ATOMIC_RELAXED);
+}
+/**
- wd_alg_clear_init() - Set the algorithm status as WD_UNINIT.
- @status: algorithm initialization status.
- */
+static inline void wd_alg_clear_init(enum wd_status *status) +{
- enum wd_status setting = WD_UNINIT;
- __atomic_store(status, &setting, __ATOMIC_RELAXED);
+}
- /**
- wd_dfx_msg_cnt() - Message counter interface for ctx
- @msg: Shared memory addr.
diff --git a/wd_aead.c b/wd_aead.c index d43ace1..c00d8f9 100644 --- a/wd_aead.c +++ b/wd_aead.c @@ -28,6 +28,7 @@ static int g_aead_mac_len[WD_DIGEST_TYPE_MAX] = { }; struct wd_aead_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; struct wd_aead_driver *driver;
@@ -389,24 +390,29 @@ static int aead_param_check(struct wd_aead_sess *sess, int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_aead_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_AEAD_EPOLL_EN", &wd_aead_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_aead_setting.config, config); if (ret)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_aead_setting.sched, sched); if (ret < 0)
goto out;
#ifdef WD_STATIC_DRVgoto out_clear_ctx_config; /* set driver */
@@ -418,33 +424,37 @@ int wd_aead_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_aead_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* init ctx related resources in specific driver */ priv = calloc(1, wd_aead_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_aead_setting.priv = priv; ret = wd_aead_setting.driver->init(&wd_aead_setting.config,
priv); if (ret < 0) { WD_ERR("failed to init aead dirver!\n");
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_aead_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_aead_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_aead_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_aead_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_aead_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_aead_setting.status); return ret; } @@ -462,6 +472,7 @@ void wd_aead_uninit(void) wd_uninit_async_request_pool(&wd_aead_setting.pool); wd_clear_sched(&wd_aead_setting.sched); wd_clear_ctx_config(&wd_aead_setting.config);
- wd_alg_clear_init(&wd_aead_setting.status); } static void fill_request_msg(struct wd_aead_msg *msg, struct
wd_aead_req *req, diff --git a/wd_cipher.c b/wd_cipher.c index 3d00598..ec9b3cc 100644 --- a/wd_cipher.c +++ b/wd_cipher.c @@ -42,6 +42,7 @@ static const unsigned char des_weak_keys[DES_WEAK_KEY_NUM][DES_KEY_SIZE] = { }; struct wd_cipher_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; void *sched_ctx;
@@ -228,24 +229,29 @@ void wd_cipher_free_sess(handle_t h_sess) int wd_cipher_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_cipher_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_CIPHER_EPOLL_EN", &wd_cipher_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_cipher_setting.config, config); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_cipher_setting.sched, sched); if (ret < 0)
goto out;
#ifdef WD_STATIC_DRV /* set driver */goto out_clear_ctx_config;
@@ -257,33 +263,37 @@ int wd_cipher_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_cipher_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* init ctx related resources in specific driver */ priv = calloc(1, wd_cipher_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_cipher_setting.priv = priv; ret =
wd_cipher_setting.driver->init(&wd_cipher_setting.config, priv); if (ret < 0) {
WD_ERR("hisi sec init failed.\n");
goto out_init;
WD_ERR("failed to do dirver init, ret = %d.\n", ret);
goto out_free_priv; }
- wd_alg_set_init(&wd_cipher_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_cipher_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_cipher_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_cipher_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_cipher_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_cipher_setting.status); return ret; } @@ -301,6 +311,7 @@ void wd_cipher_uninit(void) wd_uninit_async_request_pool(&wd_cipher_setting.pool); wd_clear_sched(&wd_cipher_setting.sched); wd_clear_ctx_config(&wd_cipher_setting.config);
- wd_alg_clear_init(&wd_cipher_setting.status); } static void fill_request_msg(struct wd_cipher_msg *msg,
diff --git a/wd_comp.c b/wd_comp.c index eacebd3..44593a6 100644 --- a/wd_comp.c +++ b/wd_comp.c @@ -41,6 +41,7 @@ struct wd_comp_sess { }; struct wd_comp_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; struct wd_comp_driver *driver;
@@ -81,24 +82,29 @@ void wd_comp_set_driver(struct wd_comp_driver *drv) int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_comp_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_COMP_EPOLL_EN", &wd_comp_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_comp_setting.config, config); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_comp_setting.sched, sched); if (ret < 0)
goto out;
goto out_clear_ctx_config; /* * Fix me: ctx could be passed into wd_comp_set_static_drv to
help to * choose static compiled vendor driver. For dynamic vendor driver, @@ -118,31 +124,36 @@ int wd_comp_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_comp_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* init ctx related resources in specific driver */ priv = calloc(1, wd_comp_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_comp_setting.priv = priv; ret = wd_comp_setting.driver->init(&wd_comp_setting.config, priv); if (ret < 0) { WD_ERR("failed to do driver init, ret = %d!\n", ret);
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_comp_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_comp_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_comp_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_comp_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_comp_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_comp_setting.status); return ret; } @@ -163,6 +174,8 @@ void wd_comp_uninit(void) /* unset config, sched, driver */ wd_clear_sched(&wd_comp_setting.sched); wd_clear_ctx_config(&wd_comp_setting.config);
- wd_alg_clear_init(&wd_comp_setting.status); } struct wd_comp_msg *wd_comp_get_msg(__u32 idx, __u32 tag)
diff --git a/wd_dh.c b/wd_dh.c index 461f04e..115d576 100644 --- a/wd_dh.c +++ b/wd_dh.c @@ -32,6 +32,7 @@ struct wd_dh_sess { }; static struct wd_dh_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; void *sched_ctx;
@@ -78,24 +79,29 @@ void wd_dh_set_driver(struct wd_dh_driver *drv) int wd_dh_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_dh_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_DH_EPOLL_EN", &wd_dh_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_dh_setting.config, config); if (ret)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_dh_setting.sched, sched); if (ret)
goto out;
#ifdef WD_STATIC_DRV wd_dh_set_static_drv();goto out_clear_ctx_config;
@@ -106,13 +112,13 @@ int wd_dh_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_dh_msg)); if (ret)
goto out_sched;
goto out_clear_sched; /* initialize ctx related resources in specific driver */ priv = calloc(1, wd_dh_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_dh_setting.priv = priv;
@@ -120,21 +126,24 @@ int wd_dh_init(struct wd_ctx_config *config, struct wd_sched *sched) wd_dh_setting.driver->alg_name); if (ret < 0) { WD_ERR("failed to init dh driver, ret= %d!\n", ret);
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_dh_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_dh_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_dh_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_dh_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_dh_setting.config);
+out_clear_init:
- wd_alg_clear_init(&wd_dh_setting.status); return ret; } @@ -156,6 +165,7 @@ void wd_dh_uninit(void) /* unset config, sched, driver */ wd_clear_sched(&wd_dh_setting.sched); wd_clear_ctx_config(&wd_dh_setting.config);
- wd_alg_clear_init(&wd_dh_setting.status); } static int fill_dh_msg(struct wd_dh_msg *msg, struct wd_dh_req *req,
diff --git a/wd_digest.c b/wd_digest.c index 43b4bc5..e4287dd 100644 --- a/wd_digest.c +++ b/wd_digest.c @@ -26,6 +26,7 @@ static int g_digest_mac_len[WD_DIGEST_TYPE_MAX] = { }; struct wd_digest_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; struct wd_digest_driver *driver;
@@ -151,24 +152,29 @@ void wd_digest_free_sess(handle_t h_sess) int wd_digest_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_digest_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_DIGEST_EPOLL_EN", &wd_digest_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_digest_setting.config, config); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_digest_setting.sched, sched); if (ret < 0)
goto out;
#ifdef WD_STATIC_DRVgoto out_clear_ctx_config; /* set driver */
@@ -180,33 +186,37 @@ int wd_digest_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_digest_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* init ctx related resources in specific driver */ priv = calloc(1, wd_digest_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_digest_setting.priv = priv; ret =
wd_digest_setting.driver->init(&wd_digest_setting.config, priv); if (ret < 0) { WD_ERR("failed to init digest dirver!\n");
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_digest_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_digest_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_digest_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_digest_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_digest_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_digest_setting.status); return ret; } @@ -225,6 +235,7 @@ void wd_digest_uninit(void) wd_clear_sched(&wd_digest_setting.sched); wd_clear_ctx_config(&wd_digest_setting.config);
- wd_alg_clear_init(&wd_digest_setting.status); } static int digest_param_check(struct wd_digest_sess *sess,
diff --git a/wd_ecc.c b/wd_ecc.c index 4cf287b..ea2f73b 100644 --- a/wd_ecc.c +++ b/wd_ecc.c @@ -64,6 +64,7 @@ struct wd_ecc_curve_list { }; static struct wd_ecc_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; void *sched_ctx;
@@ -133,24 +134,29 @@ void wd_ecc_set_driver(struct wd_ecc_driver *drv) int wd_ecc_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_ecc_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_ECC_EPOLL_EN", &wd_ecc_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_ecc_setting.config, config); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_ecc_setting.sched, sched); if (ret < 0)
goto out;
#ifdef WD_STATIC_DRV wd_ecc_set_static_drv();goto out_clear_ctx_config;
@@ -161,13 +167,13 @@ int wd_ecc_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_ecc_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* initialize ctx related resources in specific driver */ priv = calloc(1, wd_ecc_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_ecc_setting.priv = priv;
@@ -175,20 +181,24 @@ int wd_ecc_init(struct wd_ctx_config *config, struct wd_sched *sched) wd_ecc_setting.driver->alg_name); if (ret < 0) { WD_ERR("failed to init ecc driver, ret = %d!\n", ret);
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_ecc_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_ecc_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_ecc_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_ecc_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_ecc_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_ecc_setting.status); return ret; } @@ -210,6 +220,7 @@ void wd_ecc_uninit(void) /* unset config, sched, driver */ wd_clear_sched(&wd_ecc_setting.sched); wd_clear_ctx_config(&wd_ecc_setting.config);
- wd_alg_clear_init(&wd_ecc_setting.status); } static int trans_to_binpad(char *dst, const char *src,
diff --git a/wd_rsa.c b/wd_rsa.c index e76da09..a6293bf 100644 --- a/wd_rsa.c +++ b/wd_rsa.c @@ -72,6 +72,7 @@ struct wd_rsa_sess { }; static struct wd_rsa_setting {
- enum wd_status status; struct wd_ctx_config_internal config; struct wd_sched sched; void *sched_ctx;
@@ -118,24 +119,29 @@ void wd_rsa_set_driver(struct wd_rsa_driver *drv) int wd_rsa_init(struct wd_ctx_config *config, struct wd_sched *sched) { void *priv;
- bool flag; int ret;
- flag = wd_alg_try_init(&wd_rsa_setting.status);
- if (!flag)
return 0;
ret = wd_init_param_check(config, sched); if (ret)
return ret;
goto out_clear_init; ret = wd_set_epoll_en("WD_RSA_EPOLL_EN", &wd_rsa_setting.config.epoll_en); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_ctx_config(&wd_rsa_setting.config, config); if (ret < 0)
return ret;
goto out_clear_init; ret = wd_init_sched(&wd_rsa_setting.sched, sched); if (ret < 0)
goto out;
#ifdef WD_STATIC_DRV wd_rsa_set_static_drv();goto out_clear_ctx_config;
@@ -146,13 +152,13 @@ int wd_rsa_init(struct wd_ctx_config *config, struct wd_sched *sched) config->ctx_num, WD_POOL_MAX_ENTRIES, sizeof(struct wd_rsa_msg)); if (ret < 0)
goto out_sched;
goto out_clear_sched; /* initialize ctx related resources in specific driver */ priv = calloc(1, wd_rsa_setting.driver->drv_ctx_size); if (!priv) { ret = -WD_ENOMEM;
goto out_priv;
goto out_clear_pool; } wd_rsa_setting.priv = priv;
@@ -160,20 +166,24 @@ int wd_rsa_init(struct wd_ctx_config *config, struct wd_sched *sched) wd_rsa_setting.driver->alg_name); if (ret < 0) { WD_ERR("failed to init rsa driver, ret = %d!\n", ret);
goto out_init;
goto out_free_priv; }
- wd_alg_set_init(&wd_rsa_setting.status);
-out_init:return 0;
+out_free_priv: free(priv); wd_rsa_setting.priv = NULL; -out_priv: +out_clear_pool: wd_uninit_async_request_pool(&wd_rsa_setting.pool); -out_sched: +out_clear_sched: wd_clear_sched(&wd_rsa_setting.sched); -out: +out_clear_ctx_config: wd_clear_ctx_config(&wd_rsa_setting.config); +out_clear_init:
- wd_alg_clear_init(&wd_rsa_setting.status); return ret; } @@ -195,6 +205,7 @@ void wd_rsa_uninit(void) /* unset config, sched, driver */ wd_clear_sched(&wd_rsa_setting.sched); wd_clear_ctx_config(&wd_rsa_setting.config);
- wd_alg_clear_init(&wd_rsa_setting.status); } static int fill_rsa_msg(struct wd_rsa_msg *msg, struct wd_rsa_req
*req, diff --git a/wd_util.c b/wd_util.c index 04a2a5b..00dea74 100644 --- a/wd_util.c +++ b/wd_util.c @@ -1776,3 +1776,19 @@ int wd_init_param_check(struct wd_ctx_config *config, struct wd_sched *sched) return 0; }
+bool wd_alg_try_init(enum wd_status *status) +{
- enum wd_status expected;
- bool ret;
- do {
expected = WD_UNINIT;
ret = __atomic_compare_exchange_n(status, &expected,
WD_INITING, true,
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
if (expected == WD_INIT)
return false;
- } while (!ret);
- return true;
+}
.