Linux Audio

Check our new training course

Embedded Linux Audio

Check our new training course
with Creative Commons CC-BY-SA
lecture materials

Bootlin logo

Elixir Cross Referencer

Loading...
/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <ztest.h>
#include <debug/object_tracing.h>

enum obj_name {
	TIMER,
	MEM_SLAB,
	SEM,
	MUTEX,
	STACK,
	MSGQ,
	MBOX,
	PIPE,
	QUEUE
};

static inline void expiry_dummy_fn(struct k_timer *timer)
{
	ARG_UNUSED(timer);
}
static inline void stop_dummy_fn(struct k_timer *timer)
{
	ARG_UNUSED(timer);
}

K_TIMER_DEFINE(ktimer, expiry_dummy_fn, stop_dummy_fn);
K_MEM_SLAB_DEFINE(kmslab, 8, 2, 8);
K_SEM_DEFINE(ksema, 0, 1);
K_MUTEX_DEFINE(kmutex);
K_STACK_DEFINE(kstack, 512);
K_MSGQ_DEFINE(kmsgq, 4, 2, 4);
K_MBOX_DEFINE(kmbox);
K_PIPE_DEFINE(kpipe, 256, 4);
K_QUEUE_DEFINE(kqueue);

static struct k_timer timer;
static struct k_mem_slab mslab;
static struct k_sem sema;
static struct k_mutex mutex;
static struct k_stack stack;
static struct k_msgq msgq;
static struct k_mbox mbox;
static struct k_pipe pipe;
static struct k_queue queue;

#define BLOCK_SIZE 8
#define NUM_BLOCKS 4

static char __aligned(8) slab[BLOCK_SIZE * NUM_BLOCKS];
static stack_data_t sdata[BLOCK_SIZE * NUM_BLOCKS];
static char buffer[BLOCK_SIZE * NUM_BLOCKS];
static char data[] = "test";

static void get_obj_count(int obj_type)
{
	void *obj_list;
	int obj_found = 0;

	switch (obj_type) {
	case TIMER:
		k_timer_init(&timer, expiry_dummy_fn, stop_dummy_fn);

		obj_list = SYS_TRACING_HEAD(struct k_timer, k_timer);
		while (obj_list != NULL) {
			/* TESTPOINT: Check if the object created
			 * is added to the list
			 */
			if (obj_list == &ktimer || obj_list == &timer) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_timer, k_timer,
						    obj_list);
		}
		zassert_equal(obj_found, 2,  "Didn't find timer objects");
		break;
	case MEM_SLAB:
		k_mem_slab_init(&mslab, slab, BLOCK_SIZE, NUM_BLOCKS);

		obj_list = SYS_TRACING_HEAD(struct k_mem_slab, k_mem_slab);
		while (obj_list != NULL) {
			if (obj_list == &kmslab || obj_list == &mslab) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_mem_slab,
						    k_mem_slab, obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find mem_slab objects");
		break;
	case SEM:
		k_sem_init(&sema, 0, 1);

		obj_list = SYS_TRACING_HEAD(struct k_sem, k_sem);
		while (obj_list != NULL) {
			if (obj_list == &ksema || obj_list == &sema) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_sem, k_sem,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find semaphore objects");
		break;
	case MUTEX:
		k_mutex_init(&mutex);

		obj_list = SYS_TRACING_HEAD(struct k_mutex, k_mutex);
		while (obj_list != NULL) {
			if (obj_list == &kmutex || obj_list == &mutex) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_mutex, k_mutex,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find mutex objects");
		break;
	case STACK:
		k_stack_init(&stack, sdata, NUM_BLOCKS);

		obj_list = SYS_TRACING_HEAD(struct k_stack, k_stack);
		while (obj_list != NULL) {
			if (obj_list == &kstack || obj_list == &stack) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_stack, k_stack,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find stack objects");
		break;
	case MSGQ:
		k_msgq_init(&msgq, buffer, BLOCK_SIZE, NUM_BLOCKS);

		obj_list = SYS_TRACING_HEAD(struct k_msgq, k_msgq);
		while (obj_list != NULL) {
			if (obj_list == &kmsgq || obj_list == &msgq) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_msgq, k_msgq,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find msgq objects");
		break;
	case MBOX:
		k_mbox_init(&mbox);

		obj_list = SYS_TRACING_HEAD(struct k_mbox, k_mbox);
		while (obj_list != NULL) {
			if (obj_list == &kmbox || obj_list == &mbox) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_mbox, k_mbox,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find mbox objects");
		break;
	case PIPE:
		k_pipe_init(&pipe, data, 8);

		obj_list = SYS_TRACING_HEAD(struct k_pipe, k_pipe);
		while (obj_list != NULL) {
			if (obj_list == &kpipe || obj_list == &pipe) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_pipe, k_pipe,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find pipe objects");
		break;
	case QUEUE:
		k_queue_init(&queue);

		obj_list = SYS_TRACING_HEAD(struct k_queue, k_queue);
		while (obj_list != NULL) {
			if (obj_list == &kqueue || obj_list == &queue) {
				obj_found++;
			}
			obj_list = SYS_TRACING_NEXT(struct k_queue, k_queue,
						    obj_list);
		}
		zassert_equal(obj_found, 2, "Didn't find queue objects\n");
		break;
	default:
		zassert_unreachable("Undefined kernel object");
	}
}

/**
 * @brief Verify tracing of kernel objects
 * @details Statically create kernel objects and check if they are added to
 *          trace object list with object tracing enabled.
 * @ingroup kernel_objtracing_tests
 * @see SYS_TRACING_HEAD(), SYS_TRACING_NEXT()
 */
void test_obj_tracing(void)
{
	for (int i = TIMER; i < QUEUE; i++) {
		get_obj_count(i);
	}
}