kernel/test: Use custom code in object tracing tests

Microkernel and nanokernel versions of the test now use distinct
sets of source files. This eliminates the dependency on the
MICROKERNEL and NANOKERNEL configuration options, which the
unified kernel doesn't set correctly in all cases.

Change-Id: I59e1d4a73265a433f526d030d2fd04d4b8de1973
Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
This commit is contained in:
Allan Stephens 2016-11-01 16:06:05 -05:00 committed by Anas Nashif
parent 52b519d471
commit 7dabe23485
11 changed files with 316 additions and 124 deletions

View file

@ -2,10 +2,9 @@ Test Description
----------------
The object tracing test is a sanity test to verify that the
object tracing API remains healthy on both the nanokernel and
microkernel.
object tracing API remains healthy.
It uses the philsophers as a common application that implements
It uses the philsophers as an application that implements
multiple taks that are synchronized with mutexes.
The application initializes their objects and starts the philosophers'

View file

@ -38,38 +38,30 @@
#define IPM_THREAD 0
#endif /* CONFIG_IPM_CONSOLE_RECEIVER && CONFIG_PRINTK*/
#ifdef CONFIG_NANOKERNEL
#define OBJ_LIST_NAME nano_sem
#define OBJ_LIST_TYPE struct nano_sem
/* We expect N_PHILOSPHERS fibers and:
* 1 Background task
* 1 The object monitor fiber
* 1 IPM console fiber if enabled
/* Must account for:
* N Philosopher tasks
* 1 Object monitor task
* 1 Microkernel idle task
* 1 Microkernel server fiber
* 1 IPM console fiber
*
* Also have philosopher demo task, but it terminates early on during the test
* so we don't need to account for it.
*/
#define DELTA_THREADS 2
static inline int test_task_tracing(void)
{
return 1;
}
#define TOTAL_FIBERS (1 + IPM_THREAD)
#define TOTAL_TASKS (N_PHILOSOPHERS + 2)
#define TOTAL_THREADS (TOTAL_FIBERS + TOTAL_TASKS)
#else /*CONFIG_MICROKERNEL*/
#define OBJ_LIST_NAME micro_mutex
#define OBJ_LIST_TYPE struct _k_mutex_struct
/* We expect N_PHILOSPHERS tasks and:
* 1 Phil demo task
* 1 The object monitor task
* 1 Task scheduler fiber
* 1 IPM console fiber if enabled
*/
#define DELTA_THREADS 3
static inline int test_task_tracing(void)
{
int obj_counter = 0;
struct k_task *task_list = NULL;
struct k_task *task_list =
(struct k_task *)SYS_TRACING_HEAD(struct k_task, micro_task);
task_list = (struct k_task *)SYS_TRACING_HEAD(struct k_task, micro_task);
while (task_list != NULL) {
TC_PRINT("TASK ID: 0x%x, PRIORITY: %d, GROUP %d\n",
task_list->id, task_list->priority, task_list->group);
@ -79,8 +71,7 @@ static inline int test_task_tracing(void)
}
TC_PRINT("TASK QUANTITY: %d\n", obj_counter);
/*k_server fiber does not have a k_task structure*/
if (obj_counter == N_PHILOSOPHERS + DELTA_THREADS - 1) {
if (obj_counter == TOTAL_TASKS) {
TC_END_RESULT(TC_PASS);
return 1;
}
@ -89,8 +80,6 @@ static inline int test_task_tracing(void)
return 0;
}
#endif /*CONFIG_NANOKERNEL*/
static inline int test_thread_monitor(void)
{
int obj_counter = 0;
@ -105,12 +94,13 @@ static inline int test_thread_monitor(void)
TC_PRINT("FIBER: %p FLAGS: 0x%x\n",
thread_list, thread_list->flags);
}
thread_list = (struct tcs *)SYS_THREAD_MONITOR_NEXT(thread_list);
thread_list =
(struct tcs *)SYS_THREAD_MONITOR_NEXT(thread_list);
obj_counter++;
}
TC_PRINT("THREAD QUANTITY: %d\n", obj_counter);
if (obj_counter == N_PHILOSOPHERS + DELTA_THREADS + IPM_THREAD) {
if (obj_counter == TOTAL_THREADS) {
TC_END_RESULT(TC_PASS);
return 1;
}
@ -130,11 +120,12 @@ void object_monitor(void)
obj_counter = 0;
obj_list = SYS_TRACING_HEAD(OBJ_LIST_TYPE, OBJ_LIST_NAME);
while (obj_list != NULL) {
TC_PRINT("SEMAPHORE REF: %p\n", obj_list);
obj_list = SYS_TRACING_NEXT(OBJ_LIST_TYPE, OBJ_LIST_NAME, obj_list);
TC_PRINT("MUTEX REF: %p\n", obj_list);
obj_list = SYS_TRACING_NEXT(OBJ_LIST_TYPE, OBJ_LIST_NAME,
obj_list);
obj_counter++;
}
TC_PRINT("SEMAPHORE QUANTITY: %d\n", obj_counter);
TC_PRINT("MUTEX QUANTITY: %d\n", obj_counter);
if (obj_counter == N_PHILOSOPHERS) {
TC_END_RESULT(TC_PASS);

View file

@ -20,47 +20,13 @@
#include <tc_util.h>
#include "phil.h"
#ifdef CONFIG_NANOKERNEL
#define FORK(x) (&forks[x])
#define TAKE(x) nano_fiber_sem_take(x, TICKS_UNLIMITED)
#define GIVE(x) nano_fiber_sem_give(x)
#else /* ! CONFIG_NANOKERNEL */
#define FORK(x) forks[x]
#define TAKE(x) task_mutex_lock(x, TICKS_UNLIMITED)
#define GIVE(x) task_mutex_unlock(x)
#endif /* CONFIG_NANOKERNEL */
#define FORK(x) forks[x]
#define TAKE(x) task_mutex_lock(x, TICKS_UNLIMITED)
#define GIVE(x) task_mutex_unlock(x)
#define RANDDELAY(x) my_delay(((sys_tick_get_32() * ((x) + 1)) & 0x1f) + 1)
#define RANDDELAY(x) task_sleep(((sys_tick_get_32() * ((x) + 1)) & 0x1f) + 1)
#ifdef CONFIG_NANOKERNEL
/* externs */
extern struct nano_sem forks[N_PHILOSOPHERS];
#else /* ! CONFIG_NANOKERNEL */
kmutex_t forks[] = {fork_mutex0, fork_mutex1, fork_mutex2, fork_mutex3, fork_mutex4};
#endif /* CONFIG_NANOKERNEL */
/**
*
* @brief Wait for a number of ticks to elapse
*
* @param ticks Number of ticks to delay.
*
* @return N/A
*/
static void my_delay(int ticks)
{
#ifdef CONFIG_MICROKERNEL
task_sleep(ticks);
#else
struct nano_timer timer;
nano_timer_init(&timer, (void *) 0);
nano_fiber_timer_start(&timer, ticks);
nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
#endif
}
/**
*
@ -75,13 +41,8 @@ static void my_delay(int ticks)
void phil_entry(void)
{
int counter;
#ifdef CONFIG_NANOKERNEL
struct nano_sem *f1; /* fork #1 */
struct nano_sem *f2; /* fork #2 */
#else
kmutex_t f1; /* fork #1 */
kmutex_t f2; /* fork #2 */
#endif
static int myId; /* next philosopher ID */
int pri = irq_lock(); /* interrupt lock level */
int id = myId++; /* current philosopher ID */

View file

@ -19,48 +19,6 @@
#include <zephyr.h>
#include "phil.h"
#ifdef CONFIG_NANOKERNEL
#define STSIZE 1024
extern void phil_entry(void);
extern void object_monitor(void);
char __stack phil_stack[N_PHILOSOPHERS][STSIZE];
char __stack mon_stack[STSIZE];
struct nano_sem forks[N_PHILOSOPHERS];
#endif /* CONFIG_NANOKERNEL */
#ifdef CONFIG_NANOKERNEL
/**
*
* @brief Nanokernel entry point
*
*/
int main(void)
{
int i;
for (i = 0; i < N_PHILOSOPHERS; i++) {
nano_sem_init(&forks[i]);
nano_task_sem_give(&forks[i]);
}
/* create philosopher fibers */
for (i = 0; i < N_PHILOSOPHERS; i++) {
task_fiber_start(&phil_stack[i][0], STSIZE,
(nano_fiber_entry_t) phil_entry, 0, 0, 6, 0);
}
/* create object counter monitor*/
task_fiber_start(mon_stack, STSIZE,
(nano_fiber_entry_t) object_monitor, 0, 0, 7, 0);
return 0;
}
#else
/**
*
* @brief Routine to start dining philosopher demo
@ -72,4 +30,3 @@ void phil_demo(void)
task_group_start(PHI);
task_group_start(MON);
}
#endif

View file

@ -1,6 +1,5 @@
KERNEL_TYPE = nano
BOARD ?= qemu_x86
SOURCE_DIR = $(ZEPHYR_BASE)/tests/legacy/kernel/test_obj_tracing/microkernel/src
CONF_FILE = prj.conf
include ${ZEPHYR_BASE}/Makefile.inc

View file

@ -2,10 +2,9 @@ Test Description
----------------
The object tracing test is a sanity test to verify that the
object tracing API remains healthy on both the nanokernel and
microkernel.
object tracing API remains healthy.
It uses the philsophers as a common application that implements
It uses the philsophers as an application that implements
multiple fibers that are synchronized with semaphores.
The application initializes their objects and starts the philosophers'

View file

@ -0,0 +1,3 @@
ccflags-y += -I${ZEPHYR_BASE}/tests/include
obj-y = phil_fiber.o phil_task.o object_monitor.o

View file

@ -0,0 +1,116 @@
/* object_monitor.c - object monitor */
/*
* Copyright (c) 2016 Intel Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include <tc_util.h>
#include <util_test_common.h>
#include <misc/debug/object_tracing.h>
#include "phil.h"
/**
*
* @brief Thread that traverses, counts and reports
* the kernel objects in the philosophers application.
*
*/
#define TOTAL_TEST_NUMBER 2
/* 1 IPM console fiber if enabled */
#if defined(CONFIG_IPM_CONSOLE_RECEIVER) && defined(CONFIG_PRINTK)
#define IPM_THREAD 1
#else
#define IPM_THREAD 0
#endif /* CONFIG_IPM_CONSOLE_RECEIVER && CONFIG_PRINTK*/
/* Must account for:
* N Philosopher fibers
* 1 Object monitor fiber
* 1 main() task
* 1 IPM console fiber
*/
#define TOTAL_FIBERS (N_PHILOSOPHERS + 1 + IPM_THREAD)
#define TOTAL_TASKS 1
#define TOTAL_THREADS (TOTAL_FIBERS + TOTAL_TASKS)
#define OBJ_LIST_NAME nano_sem
#define OBJ_LIST_TYPE struct nano_sem
static inline int test_thread_monitor(void)
{
int obj_counter = 0;
struct tcs *thread_list = NULL;
thread_list = (struct tcs *)SYS_THREAD_MONITOR_HEAD;
while (thread_list != NULL) {
if (thread_list->prio == -1) {
TC_PRINT("TASK: %p FLAGS: 0x%x\n",
thread_list, thread_list->flags);
} else {
TC_PRINT("FIBER: %p FLAGS: 0x%x\n",
thread_list, thread_list->flags);
}
thread_list =
(struct tcs *)SYS_THREAD_MONITOR_NEXT(thread_list);
obj_counter++;
}
TC_PRINT("THREAD QUANTITY: %d\n", obj_counter);
if (obj_counter == TOTAL_THREADS) {
TC_END_RESULT(TC_PASS);
return 1;
}
TC_END_RESULT(TC_FAIL);
return 0;
}
void object_monitor(void)
{
int obj_counter;
int test_counter = 0;
void *obj_list = NULL;
TC_START("OBJECT TRACING TEST");
obj_counter = 0;
obj_list = SYS_TRACING_HEAD(OBJ_LIST_TYPE, OBJ_LIST_NAME);
while (obj_list != NULL) {
TC_PRINT("SEMAPHORE REF: %p\n", obj_list);
obj_list = SYS_TRACING_NEXT(OBJ_LIST_TYPE, OBJ_LIST_NAME,
obj_list);
obj_counter++;
}
TC_PRINT("SEMAPHORE QUANTITY: %d\n", obj_counter);
if (obj_counter == N_PHILOSOPHERS) {
TC_END_RESULT(TC_PASS);
test_counter++;
} else {
TC_END_RESULT(TC_FAIL);
}
test_counter += test_thread_monitor();
if (test_counter == TOTAL_TEST_NUMBER) {
TC_END_REPORT(TC_PASS);
} else {
TC_END_REPORT(TC_FAIL);
}
}

View file

@ -0,0 +1,18 @@
/* phil.h - dining philosophers header file*/
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define N_PHILOSOPHERS 5

View file

@ -0,0 +1,92 @@
/* phil_fiber.c - dining philosopher */
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include <tc_util.h>
#include "phil.h"
#define FORK(x) (&forks[x])
#define TAKE(x) nano_fiber_sem_take(x, TICKS_UNLIMITED)
#define GIVE(x) nano_fiber_sem_give(x)
#define RANDDELAY(x) my_delay(((sys_tick_get_32() * ((x) + 1)) & 0x1f) + 1)
/* externs */
extern struct nano_sem forks[N_PHILOSOPHERS];
/**
*
* @brief Wait for a number of ticks to elapse
*
* @param ticks Number of ticks to delay.
*
* @return N/A
*/
static void my_delay(int ticks)
{
struct nano_timer timer;
nano_timer_init(&timer, (void *) 0);
nano_fiber_timer_start(&timer, ticks);
nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
}
/**
*
* @brief Entry point to a philosopher's thread
*
* This routine runs as a task in the microkernel environment
* and as a fiber in the nanokernel environment.
*
* @return N/A
*/
void phil_entry(void)
{
int counter;
struct nano_sem *f1; /* fork #1 */
struct nano_sem *f2; /* fork #2 */
static int myId; /* next philosopher ID */
int pri = irq_lock(); /* interrupt lock level */
int id = myId++; /* current philosopher ID */
irq_unlock(pri);
/* always take the lowest fork first */
if ((id+1) != N_PHILOSOPHERS) {
f1 = FORK(id);
f2 = FORK(id + 1);
} else {
f1 = FORK(0);
f2 = FORK(id);
}
for (counter = 0; counter < 5; counter++) {
TAKE(f1);
TAKE(f2);
RANDDELAY(id);
GIVE(f2);
GIVE(f1);
RANDDELAY(id);
}
}

View file

@ -0,0 +1,57 @@
/* phil_task.c - dining philosophers */
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zephyr.h>
#include "phil.h"
#define STSIZE 1024
extern void phil_entry(void);
extern void object_monitor(void);
char __stack phil_stack[N_PHILOSOPHERS][STSIZE];
char __stack mon_stack[STSIZE];
struct nano_sem forks[N_PHILOSOPHERS];
/**
*
* @brief Nanokernel entry point
*
*/
int main(void)
{
int i;
for (i = 0; i < N_PHILOSOPHERS; i++) {
nano_sem_init(&forks[i]);
nano_task_sem_give(&forks[i]);
}
/* create philosopher fibers */
for (i = 0; i < N_PHILOSOPHERS; i++) {
task_fiber_start(&phil_stack[i][0], STSIZE,
(nano_fiber_entry_t) phil_entry, 0, 0, 6, 0);
}
/* create object counter monitor */
task_fiber_start(mon_stack, STSIZE,
(nano_fiber_entry_t) object_monitor, 0, 0, 7, 0);
return 0;
}