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:
Andy Ross 2018-01-25 14:09:24 -08:00 committed by Anas Nashif
commit 73678c4388
4 changed files with 116 additions and 0 deletions

View 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)

View file

@ -0,0 +1,2 @@
CONFIG_ZTEST=y
CONFIG_SMP=y

View 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);
}

View file

@ -0,0 +1,3 @@
tests:
test:
platform_whitelist: esp32