1 /*
2  * Copyright (c) 2018 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <zephyr.h>
7 #include <ztest.h>
8 #include <spinlock.h>
9 
10 BUILD_ASSERT(CONFIG_MP_NUM_CPUS > 1);
11 
12 static struct k_spinlock lock;
13 static struct k_spinlock mylock;
14 static k_spinlock_key_t key;
15 
16 static ZTEST_DMEM volatile bool valid_assert;
17 
set_assert_valid(bool valid)18 static inline void set_assert_valid(bool valid)
19 {
20 	valid_assert = valid;
21 }
22 
action_after_assert_fail(void)23 static void action_after_assert_fail(void)
24 {
25 	k_spin_unlock(&lock, key);
26 
27 	ztest_test_pass();
28 }
29 
30 #ifdef CONFIG_ASSERT_NO_FILE_INFO
assert_post_action(void)31 void assert_post_action(void)
32 #else
33 void assert_post_action(const char *file, unsigned int line)
34 #endif
35 {
36 #ifndef CONFIG_ASSERT_NO_FILE_INFO
37 	ARG_UNUSED(file);
38 	ARG_UNUSED(line);
39 #endif
40 
41 	printk("Caught an assert.\n");
42 
43 	if (valid_assert) {
44 		valid_assert = false; /* reset back to normal */
45 		printk("Assert error expected as part of test case.\n");
46 
47 		/* do some action after fatal error happened */
48 		action_after_assert_fail();
49 	} else {
50 		printk("Assert failed was unexpected, aborting...\n");
51 #ifdef CONFIG_USERSPACE
52 	/* User threads aren't allowed to induce kernel panics; generate
53 	 * an oops instead.
54 	 */
55 		if (k_is_user_context()) {
56 			k_oops();
57 		}
58 #endif
59 		k_panic();
60 	}
61 }
62 
63 
64 /**
65  * @brief Test spinlock cannot be recursive
66  *
67  * @details Validate using spinlock recursive will trigger assertion.
68  *
69  * @ingroup kernel_spinlock_tests
70  *
71  * @see k_spin_lock()
72  */
test_spinlock_no_recursive(void)73 void test_spinlock_no_recursive(void)
74 {
75 	k_spinlock_key_t re;
76 
77 	key = k_spin_lock(&lock);
78 
79 	set_assert_valid(true);
80 	re = k_spin_lock(&lock);
81 
82 	ztest_test_fail();
83 }
84 
85 /**
86  * @brief Test unlocking incorrect spinlock
87  *
88  * @details Validate unlocking incorrect spinlock will trigger assertion.
89  *
90  * @ingroup kernel_spinlock_tests
91  *
92  * @see k_spin_unlock()
93  */
test_spinlock_unlock_error(void)94 void test_spinlock_unlock_error(void)
95 {
96 	key = k_spin_lock(&lock);
97 
98 	set_assert_valid(true);
99 	k_spin_unlock(&mylock, key);
100 
101 	ztest_test_fail();
102 }
103 
104 /**
105  * @brief Test unlocking incorrect spinlock
106  *
107  * @details Validate unlocking incorrect spinlock will trigger assertion.
108  *
109  * @ingroup kernel_spinlock_tests
110  *
111  * @see k_spin_release()
112  */
test_spinlock_release_error(void)113 void test_spinlock_release_error(void)
114 {
115 	key = k_spin_lock(&lock);
116 
117 	set_assert_valid(true);
118 	k_spin_release(&mylock);
119 
120 	ztest_test_fail();
121 }
122