tests/kernel: Add spinlock test
Simple test of spinlock semantics. Bounce between two CPUs locking and releasing, validating that nothing changes at unexpected times. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
7a023cfb89
commit
73678c4388
4 changed files with 116 additions and 0 deletions
4
tests/kernel/spinlock/CMakeLists.txt
Normal file
4
tests/kernel/spinlock/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(NONE)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
2
tests/kernel/spinlock/prj.conf
Normal file
2
tests/kernel/spinlock/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_SMP=y
|
107
tests/kernel/spinlock/src/main.c
Normal file
107
tests/kernel/spinlock/src/main.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <zephyr.h>
|
||||
#include <tc_util.h>
|
||||
#include <ztest.h>
|
||||
#include <kernel.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
#define CPU1_STACK_SIZE 1024
|
||||
|
||||
K_THREAD_STACK_DEFINE(cpu1_stack, CPU1_STACK_SIZE);
|
||||
|
||||
static struct k_spinlock bounce_lock;
|
||||
|
||||
volatile int bounce_owner, bounce_done;
|
||||
|
||||
void test_spinlock_basic(void)
|
||||
{
|
||||
k_spinlock_key_t key;
|
||||
static struct k_spinlock l;
|
||||
|
||||
zassert_true(!l.locked, "Spinlock initialized to locked");
|
||||
|
||||
key = k_spin_lock(&l);
|
||||
|
||||
zassert_true(l.locked, "Spinlock failed to lock");
|
||||
|
||||
k_spin_unlock(&l, key);
|
||||
|
||||
zassert_true(!l.locked, "Spinlock failed to unlock");
|
||||
}
|
||||
|
||||
void bounce_once(int id)
|
||||
{
|
||||
int i, locked;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
/* Take the lock, check last owner and release if it was us.
|
||||
* Wait for us to get the lock "after" another CPU
|
||||
*/
|
||||
locked = 0;
|
||||
for (i = 0; i < 10000; i++) {
|
||||
key = k_spin_lock(&bounce_lock);
|
||||
|
||||
if (bounce_owner != id) {
|
||||
locked = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
k_spin_unlock(&bounce_lock, key);
|
||||
k_busy_wait(100);
|
||||
}
|
||||
|
||||
if (!locked && bounce_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
zassert_true(locked, "Other cpu did not get lock in 10000 tries\n");
|
||||
|
||||
/* Mark us as the owner, spin for a while validating that we
|
||||
* never see another owner write to the protected data.
|
||||
*/
|
||||
bounce_owner = id;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
zassert_true(bounce_owner == id, "Locked data changed");
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
k_spin_unlock(&bounce_lock, key);
|
||||
}
|
||||
|
||||
void cpu1_fn(int key, void *arg)
|
||||
{
|
||||
ARG_UNUSED(key);
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
while (1) {
|
||||
bounce_once(4321);
|
||||
}
|
||||
}
|
||||
|
||||
void test_spinlock_bounce(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
_arch_start_cpu(1, cpu1_stack, CPU1_STACK_SIZE, cpu1_fn, 0);
|
||||
|
||||
k_busy_wait(10);
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
bounce_once(1234);
|
||||
}
|
||||
|
||||
bounce_done = 1;
|
||||
}
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
ztest_test_suite(test_spinlock,
|
||||
ztest_unit_test(test_spinlock_basic),
|
||||
ztest_unit_test(test_spinlock_bounce));
|
||||
ztest_run_test_suite(test_spinlock);
|
||||
}
|
3
tests/kernel/spinlock/testcase.yaml
Normal file
3
tests/kernel/spinlock/testcase.yaml
Normal file
|
@ -0,0 +1,3 @@
|
|||
tests:
|
||||
test:
|
||||
platform_whitelist: esp32
|
Loading…
Add table
Add a link
Reference in a new issue