tests: kernel: import obj_tracing test to unified kernel

obj_tracing test from legacy modified to use unified APIs
directly.

Jira: ZEP-932

Change-Id: Ib5d300334e527b842668be076c94c40b65d7cbe4
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
This commit is contained in:
Jithu Joseph 2017-02-06 16:09:38 -08:00 committed by Anas Nashif
commit b0f2e3ef14
9 changed files with 295 additions and 0 deletions

View file

@ -0,0 +1,4 @@
BOARD ?= qemu_x86
CONF_FILE = prj.conf
include ${ZEPHYR_BASE}/Makefile.test

View file

@ -0,0 +1,43 @@
Test Description
----------------
The object tracing test is a sanity test to verify that the
object tracing API remains healthy.
It uses the philsophers as an application that implements
multiple threads that are synchronized with semaphores.
The application initializes their objects and starts the philosophers'
thread interaction. A specific thread, called object monitor, accesses
the object tracing API and reports the number of expected objects.
The sanity test script expects each test to finish its execution
and then it considers the test completed. For that reason the
philosophers' threads execute a finite number of iterations. After
that the application execution ends.
Sample Output
--------------
***** BOOTING ZEPHYR OS vxxxx - BUILD: yyyyy *****
tc_start() - OBJECT TRACING TEST
SEMAPHORE REF: 0x001031f0
SEMAPHORE REF: 0x001031dc
SEMAPHORE REF: 0x001031c8
SEMAPHORE REF: 0x001031b4
SEMAPHORE REF: 0x001031a0
SEMAPHORE QUANTITY: 5
===================================================================
PASS - object_monitor.
COOP: 0x00102da0 OPTIONS: 0x00, STATE: 0x00
COOP: 0x00104204 OPTIONS: 0x00, STATE: 0x00
COOP: 0x00103e04 OPTIONS: 0x00, STATE: 0x00
COOP: 0x00103a04 OPTIONS: 0x00, STATE: 0x02
COOP: 0x00103604 OPTIONS: 0x00, STATE: 0x02
COOP: 0x00103204 OPTIONS: 0x00, STATE: 0x00
PREMPT: 0x00105340 OPTIONS: 0x00, STATE: 0x02
COOP: 0x00104e40 OPTIONS: 0x01, STATE: 0x00
THREAD QUANTITY: 8
===================================================================
PASS - test_thread_monitor.
===================================================================
PROJECT EXECUTION SUCCESSFUL

View file

@ -0,0 +1,3 @@
CONFIG_DEBUG_TRACING_KERNEL_OBJECTS=y
CONFIG_THREAD_MONITOR=y

View file

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

View file

@ -0,0 +1,49 @@
/* phil_task.c - dining philosophers */
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#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 k_sem forks[N_PHILOSOPHERS];
/**
*
* @brief Nanokernel entry point
*
*/
int main(void)
{
int i;
for (i = 0; i < N_PHILOSOPHERS; i++) {
k_sem_init(&forks[i], 0, 1);
k_sem_give(&forks[i]);
}
/* create philosopher threads */
for (i = 0; i < N_PHILOSOPHERS; i++) {
k_thread_spawn(&phil_stack[i][0], STSIZE,
(k_thread_entry_t)phil_entry, NULL, NULL, NULL,
K_PRIO_COOP(6), 0, K_NO_WAIT);
}
/* create object counter monitor thread */
k_thread_spawn(mon_stack, STSIZE,
(k_thread_entry_t)object_monitor, NULL, NULL, NULL,
K_PRIO_COOP(7), 0, K_NO_WAIT);
return 0;
}

View file

@ -0,0 +1,114 @@
/* object_monitor.c - object monitor */
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <tc_util.h>
#include <util_test_common.h>
#include <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 threads
* 1 Object monitor thread
* 1 System idle thread
* 1 System workqueue thread
* 1 IPM console thread
*/
void *force_sys_work_q_in = (void *)&k_sys_work_q;
#define TOTAL_THREADS (N_PHILOSOPHERS + 3 + IPM_THREAD)
#define OBJ_LIST_NAME k_sem
#define OBJ_LIST_TYPE struct k_sem
static inline int test_thread_monitor(void)
{
int obj_counter = 0;
struct k_thread *thread_list = NULL;
/* wait a bit to allow any initialization-only threads to terminate */
k_sleep(100);
thread_list = (struct k_thread *)SYS_THREAD_MONITOR_HEAD;
while (thread_list != NULL) {
if (thread_list->base.prio == -1) {
TC_PRINT("PREMPT: %p OPTIONS: 0x%02x, STATE: 0x%02x\n",
thread_list,
thread_list->base.user_options,
thread_list->base.thread_state);
} else {
TC_PRINT("COOP: %p OPTIONS: 0x%02x, STATE: 0x%02x\n",
thread_list,
thread_list->base.user_options,
thread_list->base.thread_state);
}
thread_list =
(struct k_thread *)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,8 @@
/* phil.h - dining philosophers header file*/
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define N_PHILOSOPHERS 5

View file

@ -0,0 +1,66 @@
/* phil_thread.c - dining philosopher */
/*
* Copyright (c) 2011-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <tc_util.h>
#include "phil.h"
#define FORK(x) (&forks[x])
#define TAKE(x) k_sem_take(x, K_FOREVER)
#define GIVE(x) k_sem_give(x)
#define RANDDELAY(x) k_sleep(10 * (x) + 1)
/* externs */
extern struct k_sem forks[N_PHILOSOPHERS];
/**
*
* @brief Entry point to a philosopher's thread
*
* This routine runs as a task in the microkernel environment
* and as a thread in the nanokernel environment.
*
* @return N/A
*/
void phil_entry(void)
{
int counter;
struct k_sem *f1; /* fork #1 */
struct k_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,5 @@
[test]
tags = core
# Make sure it has enough memory
filter = not ((CONFIG_DEBUG or CONFIG_ASSERT)) and ( CONFIG_SRAM_SIZE >= 32
or CONFIG_DCCM_SIZE >= 32 or CONFIG_RAM_SIZE >= 32)