Kernel timeouts have always been a 32 bit integer despite the existence of generation macros, and existing code has been inconsistent about using them. Upcoming commits are going to make the timeout arguments opaque, so fix things up to be rigorously correct. Changes include: + Adding a K_TIMEOUT_EQ() macro for code that needs to compare timeout values for equality (e.g. with K_FOREVER or K_NO_WAIT). + Adding a k_msleep() synonym for k_sleep() which can continue to take integral arguments as k_sleep() moves away to timeout arguments. + Pervasively using the K_MSEC(), K_SECONDS(), et. al. macros to generate timeout arguments. + Removing the usage of K_NO_WAIT as the final argument to K_THREAD_DEFINE(). This is just a count of milliseconds and we need to use a zero. This patch include no logic changes and should not affect generated code at all. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
96 lines
2.6 KiB
C
96 lines
2.6 KiB
C
/*
|
|
* Copyright (c) 2016 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <ztest.h>
|
|
#include <sys/atomic.h>
|
|
#define THREAD_NUM 4
|
|
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACKSIZE)
|
|
#define POOL_NUM 2
|
|
#define LOOPS 10
|
|
#define TIMEOUT K_MSEC(200)
|
|
#define BLK_SIZE_MIN _MPOOL_MINBLK
|
|
#define BLK_SIZE_MAX (4 * BLK_SIZE_MIN)
|
|
#define BLK_NUM_MIN 8
|
|
#define BLK_NUM_MAX 2
|
|
#define BLK_ALIGN sizeof(void *)
|
|
|
|
K_MEM_POOL_DEFINE(mpool1, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
|
|
K_MEM_POOL_DEFINE(mpool2, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
|
|
static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREAD_NUM, STACK_SIZE);
|
|
static struct k_thread tdata[THREAD_NUM];
|
|
static struct k_mem_pool *pools[POOL_NUM] = { &mpool1, &mpool2 };
|
|
static struct k_sem sync_sema;
|
|
static atomic_t pool_id;
|
|
|
|
/* thread entry simply invoke the APIs*/
|
|
static void tmpool_api(void *p1, void *p2, void *p3)
|
|
{
|
|
struct k_mem_block block[BLK_NUM_MIN];
|
|
int ret[BLK_NUM_MIN];
|
|
struct k_mem_pool *pool = pools[atomic_inc(&pool_id) % POOL_NUM];
|
|
|
|
(void)memset(block, 0, sizeof(block));
|
|
|
|
for (int loops = 0; loops < LOOPS; loops++) {
|
|
for (int i = 0; i < 4; i++) {
|
|
ret[i] = k_mem_pool_alloc(pool, &block[i],
|
|
BLK_SIZE_MIN, TIMEOUT);
|
|
}
|
|
ret[4] = k_mem_pool_alloc(pool, &block[4], BLK_SIZE_MAX,
|
|
TIMEOUT);
|
|
for (int i = 0; i < 5; i++) {
|
|
if (ret[i] == 0) {
|
|
k_mem_pool_free(&block[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
k_sem_give(&sync_sema);
|
|
}
|
|
|
|
/* test cases*/
|
|
/**
|
|
* @brief Test alloc and free on different priority threads
|
|
*
|
|
* @ingroup kernel_memory_pool_tests
|
|
*
|
|
* @details The test creates 4 threads of equal priority and
|
|
* invokes memory pool APIs on same memory domain. Checks for
|
|
* the synchronization of threads on the resource memory pool.
|
|
* Each thread allocates 4 blocks of size 4 bytes (all blocks
|
|
* in memory pool) with timeout of 200 ms and frees up all the
|
|
* blocks
|
|
*/
|
|
void test_mpool_threadsafe(void)
|
|
{
|
|
k_tid_t tid[THREAD_NUM];
|
|
|
|
k_sem_init(&sync_sema, 0, THREAD_NUM);
|
|
|
|
/* create multiple threads to invoke same memory pool APIs*/
|
|
for (int i = 0; i < THREAD_NUM; i++) {
|
|
tid[i] = k_thread_create(&tdata[i], tstack[i], STACK_SIZE,
|
|
tmpool_api, NULL, NULL, NULL,
|
|
K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
|
|
}
|
|
/* TESTPOINT: all threads complete and exit the entry function*/
|
|
for (int i = 0; i < THREAD_NUM; i++) {
|
|
k_sem_take(&sync_sema, K_FOREVER);
|
|
}
|
|
|
|
/* test case tear down*/
|
|
for (int i = 0; i < THREAD_NUM; i++) {
|
|
k_thread_abort(tid[i]);
|
|
}
|
|
}
|
|
|
|
void test_main(void)
|
|
{
|
|
ztest_test_suite(mpool_threadsafe,
|
|
ztest_unit_test(test_mpool_threadsafe));
|
|
ztest_run_test_suite(mpool_threadsafe);
|
|
}
|