diff options
author | Matt Caswell <matt@openssl.org> | 2020-12-23 12:35:54 +0100 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2020-12-31 13:14:38 +0100 |
commit | ea08f8b294d129371536649463c76a81dc4d4e55 (patch) | |
tree | 87acd7f26384883dc9b5422493c562833e107ae7 /test/threadstest.c | |
parent | Add documentation for CRYPTO_atomic_or and CRYPTO_atomic_load (diff) | |
download | openssl-ea08f8b294d129371536649463c76a81dc4d4e55.tar.xz openssl-ea08f8b294d129371536649463c76a81dc4d4e55.zip |
Add a test for the new CRYPTO_atomic_* functions
Also tests the older CRYPTO_atomic_add() which was without a test
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/13733)
Diffstat (limited to 'test/threadstest.c')
-rw-r--r-- | test/threadstest.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/test/threadstest.c b/test/threadstest.c index 5f373fe75f..d7ed59781d 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -184,10 +184,86 @@ static int test_thread_local(void) return 1; } +static int test_atomic(void) +{ + int val = 0, ret = 0, testresult = 0; + uint64_t val64 = 1, ret64 = 0; + CRYPTO_RWLOCK *lock = CRYPTO_THREAD_lock_new(); + + if (!TEST_ptr(lock)) + return 0; + + if (CRYPTO_atomic_add(&val, 1, &ret, NULL)) { + /* This succeeds therefore we're on a platform with lockless atomics */ + if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret)) + goto err; + } else { + /* This failed therefore we're on a platform without lockless atomics */ + if (!TEST_int_eq(val, 0) || !TEST_int_eq(val, ret)) + goto err; + } + val = 0; + ret = 0; + + if (!TEST_true(CRYPTO_atomic_add(&val, 1, &ret, lock))) + goto err; + if (!TEST_int_eq(val, 1) || !TEST_int_eq(val, ret)) + goto err; + + if (CRYPTO_atomic_or(&val64, 2, &ret64, NULL)) { + /* This succeeds therefore we're on a platform with lockless atomics */ + if (!TEST_uint_eq((unsigned int)val64, 3) + || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64)) + goto err; + } else { + /* This failed therefore we're on a platform without lockless atomics */ + if (!TEST_uint_eq((unsigned int)val64, 1) + || !TEST_int_eq((unsigned int)ret64, 0)) + goto err; + } + val64 = 1; + ret64 = 0; + + if (!TEST_true(CRYPTO_atomic_or(&val64, 2, &ret64, lock))) + goto err; + + if (!TEST_uint_eq((unsigned int)val64, 3) + || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64)) + goto err; + + ret64 = 0; + if (CRYPTO_atomic_load(&val64, &ret64, NULL)) { + /* This succeeds therefore we're on a platform with lockless atomics */ + if (!TEST_uint_eq((unsigned int)val64, 3) + || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64)) + goto err; + } else { + /* This failed therefore we're on a platform without lockless atomics */ + if (!TEST_uint_eq((unsigned int)val64, 3) + || !TEST_int_eq((unsigned int)ret64, 0)) + goto err; + } + + ret64 = 0; + if (!TEST_true(CRYPTO_atomic_load(&val64, &ret64, lock))) + goto err; + + if (!TEST_uint_eq((unsigned int)val64, 3) + || !TEST_uint_eq((unsigned int)val64, (unsigned int)ret64)) + goto err; + + testresult = 1; + err: + + CRYPTO_THREAD_lock_free(lock); + return testresult; +} + int setup_tests(void) { ADD_TEST(test_lock); ADD_TEST(test_once); ADD_TEST(test_thread_local); + ADD_TEST(test_atomic); return 1; } |