diff options
| author | lhchavez <lhchavez@lhchavez.com> | 2020-12-20 12:45:01 -0800 |
|---|---|---|
| committer | lhchavez <lhchavez@lhchavez.com> | 2021-08-26 05:34:17 -0700 |
| commit | 74708a813d586df3ba22a81b475f6aba0498e2ef (patch) | |
| tree | f3de0ceb6e03e1b4453762864c51330e05584d7d /tests/threads | |
| parent | fabacb7c6506f0cfb4cb29031855e50f00664b6b (diff) | |
| download | libgit2-74708a813d586df3ba22a81b475f6aba0498e2ef.tar.gz | |
Homogenize semantics for atomic-related functions
There were some subtle semantic differences between the various
implementations of atomic functions. Now they behave the same, have
tests and are better documented to avoid this from happening again in
the future.
Of note:
* The semantics chosen for `git_atomic_compare_and_swap` match
`InterlockedCompareExchangePointer`/`__sync_cal_compare_and_swap` now.
* The semantics chosen for `git_atomic_add` match
`InterlockedAdd`/`__atomic_add_fetch`.
* `git_atomic_swap` and `git_atomic_load` still have a bit of semantic
difference with the gcc builtins / msvc interlocked operations, since
they require an l-value (not a pointer). If desired, this can be
homogenized.
Diffstat (limited to 'tests/threads')
| -rw-r--r-- | tests/threads/atomic.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/tests/threads/atomic.c b/tests/threads/atomic.c new file mode 100644 index 000000000..4d04a777a --- /dev/null +++ b/tests/threads/atomic.c @@ -0,0 +1,125 @@ +#include "clar_libgit2.h" + +void test_threads_atomic__atomic32_set(void) +{ + git_atomic32 v = {0}; + git_atomic32_set(&v, 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_get(void) +{ + git_atomic32 v = {1}; + cl_assert_equal_i(git_atomic32_get(&v), 1); +} + +void test_threads_atomic__atomic32_inc(void) +{ + git_atomic32 v = {0}; + cl_assert_equal_i(git_atomic32_inc(&v), 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_add(void) +{ + git_atomic32 v = {0}; + cl_assert_equal_i(git_atomic32_add(&v, 1), 1); + cl_assert_equal_i(v.val, 1); +} + +void test_threads_atomic__atomic32_dec(void) +{ + git_atomic32 v = {1}; + cl_assert_equal_i(git_atomic32_dec(&v), 0); + cl_assert_equal_i(v.val, 0); +} + +void test_threads_atomic__atomic64_set(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {0}; + git_atomic64_set(&v, 1); + cl_assert_equal_i(v.val, 1); +#endif +} + +void test_threads_atomic__atomic64_get(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {1}; + cl_assert_equal_i(git_atomic64_get(&v), 1); +#endif +} + +void test_threads_atomic__atomic64_add(void) +{ +#ifndef GIT_ARCH_64 + cl_skip(); +#else + git_atomic64 v = {0}; + cl_assert_equal_i(git_atomic64_add(&v, 1), 1); + cl_assert_equal_i(v.val, 1); +#endif +} + +void test_threads_atomic__cas_pointer(void) +{ + int *value = NULL; + int newvalue1 = 1, newvalue2 = 2; + + /* value is updated */ + cl_assert_equal_p(git_atomic_compare_and_swap(&value, NULL, &newvalue1), NULL); + cl_assert_equal_p(value, &newvalue1); + + /* value is not updated */ + cl_assert_equal_p(git_atomic_compare_and_swap(&value, NULL, &newvalue2), &newvalue1); + cl_assert_equal_p(value, &newvalue1); +} + +void test_threads_atomic__cas_intptr(void) +{ + intptr_t value = 0; + intptr_t oldvalue; + intptr_t newvalue; + + /* value is updated */ + oldvalue = 0; + newvalue = 1; + cl_assert_equal_i((intptr_t)git_atomic_compare_and_swap(&value, (void *)oldvalue, (void *)newvalue), 0); + cl_assert_equal_i(value, 1); + + /* value is not updated */ + oldvalue = 0; + newvalue = 2; + cl_assert_equal_i((intptr_t)git_atomic_compare_and_swap(&value, (void *)oldvalue, (void *)newvalue), 1); + cl_assert_equal_i(value, 1); +} + +void test_threads_atomic__swap(void) +{ + int *value = NULL; + int newvalue = 1; + + cl_assert_equal_p(git_atomic_swap(value, &newvalue), NULL); + cl_assert_equal_p(value, &newvalue); + + cl_assert_equal_p(git_atomic_swap(value, NULL), &newvalue); + cl_assert_equal_p(value, NULL); +} + +void test_threads_atomic__load_ptr(void) +{ + int value = 1; + int *ptr = &value; + cl_assert_equal_p(git_atomic_load(ptr), &value); +} + +void test_threads_atomic__load_intptr(void) +{ + intptr_t value = 1; + cl_assert_equal_i((intptr_t)git_atomic_load(value), 1); +} |
