Skip to content

Commit

Permalink
improve atomic
Browse files Browse the repository at this point in the history
  • Loading branch information
xianjimli committed Nov 18, 2024
1 parent aba6a68 commit 0bfb542
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 84 deletions.
3 changes: 3 additions & 0 deletions docs/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# 最新动态

2024/11/18
* 完善 atomic(感谢兆坤提供补丁)

2024/11/17
* 完善 TK_STRINGIZE(感谢兆坤提供补丁)
* value完善调试log(感谢兆坤提供补丁)
Expand Down
164 changes: 89 additions & 75 deletions src/tkc/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,89 @@ static inline bool_t tk_atomic_support_value_type(value_type_t type) {
}
}

/**
* @method tk_atomic_deinit
* @export none
* 释放原子操作类对象。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_deinit(tk_atomic_t* atomic);

/**
* @method tk_atomic_init
* @export none
* 初始化原子操作类对象。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
* @param {const value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_init(tk_atomic_t* atomic, const value_t* v);

/**
* @method tk_atomic_exchange
* @export none
* 原子交换操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 交换值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_exchange(tk_atomic_t* atomic, value_t* v);

/**
* @method tk_atomic_store
* @export none
* 原子写操作。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
* @param {const value_t*} v 写入值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_store(tk_atomic_t* atomic, const value_t* v);

/**
* @method tk_atomic_load
* @export none
* 原子读操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 用于返回读取值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_load(const tk_atomic_t* atomic, value_t* v);

/**
* @method tk_atomic_fetch_add
* @export none
* 原子加操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_fetch_add(tk_atomic_t* atomic, value_t* v);

/**
* @method tk_atomic_fetch_sub
* @export none
* 原子减操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static ret_t tk_atomic_fetch_sub(tk_atomic_t* atomic, value_t* v);

#if defined(WIN32) && !defined(MINGW)
#include <winnt.h>

Expand Down Expand Up @@ -651,15 +734,6 @@ struct _tk_atomic_t {
tk_mutex_t* lock;
};

/**
* @method tk_atomic_deinit
* @export none
* 释放原子操作类对象。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_deinit(tk_atomic_t* atomic) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL, RET_BAD_PARAMS);
Expand All @@ -672,16 +746,6 @@ static inline ret_t tk_atomic_deinit(tk_atomic_t* atomic) {
return ret;
}

/**
* @method tk_atomic_init
* @export none
* 初始化原子操作类对象。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
* @param {const value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_init(tk_atomic_t* atomic, const value_t* v) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);
Expand All @@ -699,43 +763,23 @@ static inline ret_t tk_atomic_init(tk_atomic_t* atomic, const value_t* v) {
return ret;
}

/**
* @method tk_atomic_exchange
* @export none
* 原子交换操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 交换值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_exchange(tk_atomic_t* atomic, value_t* v) {
ret_t ret = RET_OK;
value_t tmp;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);

ret = tk_mutex_lock(atomic->lock);
return_value_if_fail(RET_OK == ret, ret);

/* 读-修改-写 */
value_t tmp;
value_copy(&tmp, &atomic->value);
ret = value_copy(&atomic->value, v);
value_copy(v, &tmp);
error:

tk_mutex_unlock(atomic->lock);
return ret;
}

/**
* @method tk_atomic_store
* @export none
* 原子写操作。
*
* @param {tk_atomic_t*} atomic 原子操作类对象。
* @param {const value_t*} v 写入值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_store(tk_atomic_t* atomic, const value_t* v) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);
Expand All @@ -744,21 +788,11 @@ static inline ret_t tk_atomic_store(tk_atomic_t* atomic, const value_t* v) {
return_value_if_fail(RET_OK == ret, ret);

ret = value_copy(&atomic->value, v);
error:

tk_mutex_unlock(atomic->lock);
return ret;
}

/**
* @method tk_atomic_load
* @export none
* 原子读操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 用于返回读取值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_load(const tk_atomic_t* atomic, value_t* v) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);
Expand All @@ -767,21 +801,11 @@ static inline ret_t tk_atomic_load(const tk_atomic_t* atomic, value_t* v) {
return_value_if_fail(RET_OK == ret, ret);

ret = value_copy(v, &atomic->value);
error:

tk_mutex_unlock(atomic->lock);
return ret;
}

/**
* @method tk_atomic_fetch_add
* @export none
* 原子加操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_fetch_add(tk_atomic_t* atomic, value_t* v) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);
Expand All @@ -790,21 +814,11 @@ static inline ret_t tk_atomic_fetch_add(tk_atomic_t* atomic, value_t* v) {
return_value_if_fail(RET_OK == ret, ret);

ret = value_add(&atomic->value, v, &atomic->value);
error:

tk_mutex_unlock(atomic->lock);
return ret;
}

/**
* @method tk_atomic_fetch_sub
* @export none
* 原子减操作。
*
* @param {const tk_atomic_t*} atomic 原子操作类对象。
* @param {value_t*} v 值。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
static inline ret_t tk_atomic_fetch_sub(tk_atomic_t* atomic, value_t* v) {
ret_t ret = RET_OK;
return_value_if_fail(atomic != NULL && v != NULL, RET_BAD_PARAMS);
Expand All @@ -813,7 +827,7 @@ static inline ret_t tk_atomic_fetch_sub(tk_atomic_t* atomic, value_t* v) {
return_value_if_fail(RET_OK == ret, ret);

ret = value_sub(&atomic->value, v, &atomic->value);
error:

tk_mutex_unlock(atomic->lock);
return ret;
}
Expand Down
17 changes: 8 additions & 9 deletions tests/atomic_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
static tk_atomic_t s_atomic;

static void* inc_thread(void* args) {
uint32_t id = (uint32_t)tk_pointer_to_int(args);
uint64_t i = 0;
value_t v;

Expand All @@ -26,7 +25,6 @@ static void* inc_thread(void* args) {
}

static void* dec_thread(void* args) {
uint32_t id = (uint32_t)tk_pointer_to_int(args);
uint64_t i = 0;
value_t v;

Expand Down Expand Up @@ -62,13 +60,13 @@ int main(int argc, char* argv[]) {
platform_prepare();
timer_prepare(time_now_ms);

tk_atomic_init(&s_atomic, value_set_int(&v, 0));
tk_atomic_init(&s_atomic, value_set_uint64(&v, 0));

for (i = 0; i < ARRAY_SIZE(entrys); i++) {
uint32_t j = 0;
value_t tmp;

log_debug("entrys[%u] start\n", i);
log_debug("entrys[%" PRIu32 "] start\n", i);

tk_atomic_store(&s_atomic, value_set_uint64(&v, entrys_init_value[i]));

Expand All @@ -82,28 +80,29 @@ int main(int argc, char* argv[]) {
for (j = 0; j < ARRAY_SIZE(threads); j++) {
tk_thread_join(threads[j]);
tk_thread_destroy(threads[j]);
log_debug("%u stop\n", j);
log_debug("%" PRIu32 " stop\n", j);
}

entrys_time[i] = timer_manager()->get_time() - entrys_time[i];

tk_atomic_load(&s_atomic, &tmp);

entrys_result[i] = value_uint64(&tmp);
log_debug("entrys[%u] result %llu\n", i, entrys_result[i]);
log_debug("entrys[%" PRIu32 "] result %" PRIu64 "\n", i, entrys_result[i]);
}

tk_atomic_deinit(&s_atomic);

log_debug("\n");

for (i = 0; i < ARRAY_SIZE(entrys); i++) {
log_debug("entrys[%u] : time = %llu ms, result = %llu, correct = %s\n", i, entrys_time[i],
entrys_result[i], entrys_result[i] == entrys_correct[i] ? "True" : "False");
log_debug("entrys[%" PRIu32 "] : time = %" PRIu64 " ms, result = %" PRIu64 ", correct = %s\n",
i, entrys_time[i], entrys_result[i],
entrys_result[i] == entrys_correct[i] ? "True" : "False");
total_time += entrys_time[i];
}

log_debug("\ntotal time = %llu ms\n", total_time);
log_debug("\ntotal time = %" PRIu64 " ms\n", total_time);

return 0;
}

0 comments on commit 0bfb542

Please sign in to comment.