From: Ivan Orlov <ivan.orlov0322@gmail.com>
To: opensbi@lists.infradead.org
Subject: [PATCH 2/3] lib: tests: Add test for atomic_t
Date: Tue, 23 Apr 2024 16:52:44 +0100 [thread overview]
Message-ID: <20240423155245.14541-3-ivan.orlov0322@gmail.com> (raw)
In-Reply-To: <20240423155245.14541-1-ivan.orlov0322@gmail.com>
Implement the test which covers some of the functions from the
`riscv_atomic.h` header file. The test contains 9 test cases:
1) atomic read/write test
2) add/return test
3) sub/return test
4) cmpxchg test
5) atomic_xchg test
6) atomic_raw_set_bit test
7) atomic_raw_clear_bit test
8) atomic_set_bit test
9) atomic_clear_bit test
Some of the test cases operate on the `test_atomic` variable. It gets
initialized in the suite init function.
Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com>
---
lib/sbi/tests/objects.mk | 3 +
lib/sbi/tests/riscv_atomic_test.c | 143 ++++++++++++++++++++++++++++++
2 files changed, 146 insertions(+)
create mode 100644 lib/sbi/tests/riscv_atomic_test.c
diff --git a/lib/sbi/tests/objects.mk b/lib/sbi/tests/objects.mk
index 5ce188a..ba588dc 100644
--- a/lib/sbi/tests/objects.mk
+++ b/lib/sbi/tests/objects.mk
@@ -6,3 +6,6 @@ libsbi-objs-$(CONFIG_SBIUNIT) += tests/sbi_bitmap_test.o
carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += console_test_suite
libsbi-objs-$(CONFIG_SBIUNIT) += tests/sbi_console_test.o
+
+carray-sbi_unit_tests-$(CONFIG_SBIUNIT) += atomic_test_suite
+libsbi-objs-$(CONFIG_SBIUNIT) += tests/riscv_atomic_test.o
diff --git a/lib/sbi/tests/riscv_atomic_test.c b/lib/sbi/tests/riscv_atomic_test.c
new file mode 100644
index 0000000..8a17a5f
--- /dev/null
+++ b/lib/sbi/tests/riscv_atomic_test.c
@@ -0,0 +1,143 @@
+#include <sbi/sbi_unit_test.h>
+#include <sbi/riscv_atomic.h>
+#include <sbi/sbi_bitops.h>
+
+#define ATOMIC_TEST_VAL1 239l
+#define ATOMIC_TEST_VAL2 30l
+#define ATOMIC_TEST_VAL3 2024l
+
+#define ATOMIC_TEST_BIT_NUM 3
+
+#define ATOMIC_TEST_RAW_BIT_CELL 1
+#define ATOMIC_TEST_RAW_BIT_NUM 15
+
+static atomic_t test_atomic;
+
+static void atomic_test_suite_init(void)
+{
+ ATOMIC_INIT(&test_atomic, 0);
+}
+
+static void atomic_rw_test(struct sbiunit_test_case *test)
+{
+ /* We should read the same value as we've written */
+ atomic_write(&test_atomic, ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL1);
+ /* Negative value should also work */
+ atomic_write(&test_atomic, -ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), -ATOMIC_TEST_VAL1);
+}
+
+static void add_return_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_add_return(&test_atomic, ATOMIC_TEST_VAL2),
+ ATOMIC_TEST_VAL1 + ATOMIC_TEST_VAL2);
+ /* The atomic value should be updated as well */
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL1 + ATOMIC_TEST_VAL2);
+}
+
+static void sub_return_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_sub_return(&test_atomic, ATOMIC_TEST_VAL2),
+ ATOMIC_TEST_VAL1 - ATOMIC_TEST_VAL2);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL1 - ATOMIC_TEST_VAL2);
+}
+
+static void cmpxchg_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, ATOMIC_TEST_VAL1);
+ /* if current value != expected, it stays the same */
+ SBIUNIT_EXPECT_EQ(test, atomic_cmpxchg(&test_atomic, ATOMIC_TEST_VAL2, ATOMIC_TEST_VAL3),
+ ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL1);
+ /* if current value == expected, it gets updated */
+ SBIUNIT_EXPECT_EQ(test, atomic_cmpxchg(&test_atomic, ATOMIC_TEST_VAL1, ATOMIC_TEST_VAL2),
+ ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL2);
+}
+
+static void atomic_xchg_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_xchg(&test_atomic, ATOMIC_TEST_VAL2), ATOMIC_TEST_VAL1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), ATOMIC_TEST_VAL2);
+}
+
+static void atomic_raw_set_bit_test(struct sbiunit_test_case *test)
+{
+ unsigned long data[] = {0, 0, 0};
+ /* the bitpos points to the bit of one of the elements of the `data` array */
+ size_t bitpos = ATOMIC_TEST_RAW_BIT_CELL * BITS_PER_LONG + ATOMIC_TEST_RAW_BIT_NUM;
+
+ /* check if the bit we set actually gets set */
+ SBIUNIT_EXPECT_EQ(test, atomic_raw_set_bit(bitpos, data), 0);
+ SBIUNIT_EXPECT_EQ(test, data[ATOMIC_TEST_RAW_BIT_CELL], 1 << ATOMIC_TEST_RAW_BIT_NUM);
+
+ /* Other elements of the `data` array should stay untouched */
+ SBIUNIT_EXPECT_EQ(test, data[0], 0);
+ SBIUNIT_EXPECT_EQ(test, data[2], 0);
+
+ /* check that if we set the bit twice it stays set */
+ SBIUNIT_EXPECT_EQ(test, atomic_raw_set_bit(bitpos, data), 1);
+ SBIUNIT_EXPECT_EQ(test, data[ATOMIC_TEST_RAW_BIT_CELL], 1 << ATOMIC_TEST_RAW_BIT_NUM);
+}
+
+static void atomic_raw_clear_bit_test(struct sbiunit_test_case *test)
+{
+ unsigned long data[] = {~1UL, 1 << ATOMIC_TEST_RAW_BIT_NUM, ~1UL};
+ /* the bitpos points to the bit of one of the elements of the `data` array */
+ size_t bitpos = ATOMIC_TEST_RAW_BIT_CELL * BITS_PER_LONG + ATOMIC_TEST_RAW_BIT_NUM;
+
+ /* check if the bit we clear actually gets cleared */
+ SBIUNIT_EXPECT_EQ(test, atomic_raw_clear_bit(bitpos, data), 1);
+ SBIUNIT_EXPECT_EQ(test, data[ATOMIC_TEST_RAW_BIT_CELL], 0);
+
+ /* Other elements of the `data` array should stay untouched */
+ SBIUNIT_EXPECT_EQ(test, data[0], ~1UL);
+ SBIUNIT_EXPECT_EQ(test, data[2], ~1UL);
+
+ /* check that if we clear the bit twice it stays cleared */
+ SBIUNIT_EXPECT_EQ(test, atomic_raw_clear_bit(bitpos, data), 0);
+ SBIUNIT_EXPECT_EQ(test, data[ATOMIC_TEST_RAW_BIT_CELL], 0);
+}
+
+static void atomic_set_bit_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, 0);
+ SBIUNIT_EXPECT_EQ(test, atomic_set_bit(ATOMIC_TEST_BIT_NUM, &test_atomic), 0);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), 1 << ATOMIC_TEST_BIT_NUM);
+ /* If we set the bit twice, it stays 1 */
+ SBIUNIT_EXPECT_EQ(test, atomic_set_bit(ATOMIC_TEST_BIT_NUM, &test_atomic), 1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), 1 << ATOMIC_TEST_BIT_NUM);
+}
+
+static void atomic_clear_bit_test(struct sbiunit_test_case *test)
+{
+ atomic_write(&test_atomic, 1 << ATOMIC_TEST_BIT_NUM);
+ SBIUNIT_EXPECT_EQ(test, atomic_clear_bit(ATOMIC_TEST_BIT_NUM, &test_atomic), 1);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), 0);
+ /* if we clear the bit twice, it stays 0 */
+ SBIUNIT_EXPECT_EQ(test, atomic_clear_bit(ATOMIC_TEST_BIT_NUM, &test_atomic), 0);
+ SBIUNIT_EXPECT_EQ(test, atomic_read(&test_atomic), 0);
+}
+
+static struct sbiunit_test_case atomic_test_cases[] = {
+ SBIUNIT_TEST_CASE(atomic_rw_test),
+ SBIUNIT_TEST_CASE(add_return_test),
+ SBIUNIT_TEST_CASE(sub_return_test),
+ SBIUNIT_TEST_CASE(cmpxchg_test),
+ SBIUNIT_TEST_CASE(atomic_xchg_test),
+ SBIUNIT_TEST_CASE(atomic_raw_set_bit_test),
+ SBIUNIT_TEST_CASE(atomic_raw_clear_bit_test),
+ SBIUNIT_TEST_CASE(atomic_set_bit_test),
+ SBIUNIT_TEST_CASE(atomic_clear_bit_test),
+ SBIUNIT_END_CASE,
+};
+
+const struct sbiunit_test_suite atomic_test_suite = {
+ .name = "atomic_test_suite",
+ .cases = atomic_test_cases,
+ .init = atomic_test_suite_init
+};
--
2.34.1
next prev parent reply other threads:[~2024-04-23 15:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-23 15:52 [PATCH 0/3] Add two tests and improve SBIUnit Ivan Orlov
2024-04-23 15:52 ` [PATCH 1/3] lib: tests: Add test suite init function Ivan Orlov
2024-05-07 6:02 ` Anup Patel
2024-04-23 15:52 ` Ivan Orlov [this message]
2024-05-07 6:02 ` [PATCH 2/3] lib: tests: Add test for atomic_t Anup Patel
2024-04-23 15:52 ` [PATCH 3/3] lib: tests: Add test for spinlocks Ivan Orlov
2024-05-07 6:02 ` Anup Patel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240423155245.14541-3-ivan.orlov0322@gmail.com \
--to=ivan.orlov0322@gmail.com \
--cc=opensbi@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.