blob: af2022efb70e563b7f5b562ef6b2be2e943ae0f0 [file] [log] [blame]
/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#include <sys/ring_buffer.h>
#include <sys/mutex.h>
/**
* @defgroup lib_ringbuffer_tests Ringbuffer
* @ingroup all_tests
* @{
* @}
*/
#define STACKSIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
#define RINGBUFFER 256
#define LENGTH 64
#define VALUE 0xb
#define TYPE 0xc
static K_THREAD_STACK_DEFINE(thread_low_stack, STACKSIZE);
static struct k_thread thread_low_data;
static K_THREAD_STACK_DEFINE(thread_high_stack, STACKSIZE);
static struct k_thread thread_high_data;
static ZTEST_BMEM SYS_MUTEX_DEFINE(mutex);
RING_BUF_ITEM_DECLARE_SIZE(ringbuf, RINGBUFFER);
static uint32_t output[LENGTH];
static uint32_t databuffer1[LENGTH];
static uint32_t databuffer2[LENGTH];
static void data_write(uint32_t *input)
{
sys_mutex_lock(&mutex, K_FOREVER);
int ret = ring_buf_item_put(&ringbuf, TYPE, VALUE,
input, LENGTH);
zassert_equal(ret, 0, NULL);
sys_mutex_unlock(&mutex);
}
static void data_read(uint32_t *output)
{
uint16_t type;
uint8_t value, size32 = LENGTH;
int ret;
sys_mutex_lock(&mutex, K_FOREVER);
ret = ring_buf_item_get(&ringbuf, &type, &value, output, &size32);
sys_mutex_unlock(&mutex);
zassert_equal(ret, 0, NULL);
zassert_equal(type, TYPE, NULL);
zassert_equal(value, VALUE, NULL);
zassert_equal(size32, LENGTH, NULL);
if (output[0] == 1) {
zassert_equal(memcmp(output, databuffer1, size32), 0, NULL);
} else {
zassert_equal(memcmp(output, databuffer2, size32), 0, NULL);
}
}
static void thread_entry_t1(void *p1, void *p2, void *p3)
{
for (int i = 0; i < LENGTH; i++) {
databuffer1[i] = 1;
}
/* Try to write data into the ringbuffer */
data_write(databuffer1);
/* Try to get data from the ringbuffer and check */
data_read(output);
}
static void thread_entry_t2(void *p1, void *p2, void *p3)
{
for (int i = 0; i < LENGTH; i++) {
databuffer2[i] = 2;
}
/* Try to write data into the ringbuffer */
data_write(databuffer2);
/* Try to get data from the ringbuffer and check */
data_read(output);
}
/**
* @brief Test that prevent concurrent writing
* operations by using a mutex
*
* @details Define a ring buffer and a mutex,
* and then spawn two threads to read and
* write the same buffer at the same time to
* check the integrity of data reading and writing.
*
* @ingroup lib_ringbuffer_tests
*/
void test_ringbuffer_concurrent(void)
{
int old_prio = k_thread_priority_get(k_current_get());
int prio = 10;
k_thread_priority_set(k_current_get(), prio);
k_thread_create(&thread_high_data, thread_high_stack, STACKSIZE,
thread_entry_t1,
NULL, NULL, NULL,
prio + 2, 0, K_NO_WAIT);
k_thread_create(&thread_low_data, thread_low_stack, STACKSIZE,
thread_entry_t2,
NULL, NULL, NULL,
prio + 2, 0, K_NO_WAIT);
k_sleep(K_MSEC(10));
/* Wait for thread exiting */
k_thread_join(&thread_low_data, K_FOREVER);
k_thread_join(&thread_high_data, K_FOREVER);
/* Revert priority of the main thread */
k_thread_priority_set(k_current_get(), old_prio);
}