summaryrefslogblamecommitdiffstats
path: root/cpukit/include/rtems/test-scheduler.h
blob: b9e8bf2993381c8863cd3734981d204d6f7ac418 (plain) (tree)

































































































































































































































































































                                                                              
/* SPDX-License-Identifier: BSD-2-Clause */

/**
 * @file
 *
 * @ingroup RTEMSTestFramework
 *
 * @brief This header file defines the scheduler test support API.
 */

/*
 * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _RTEMS_TEST_SCHEDULER_H
#define _RTEMS_TEST_SCHEDULER_H

#include <rtems/test.h>
#include <rtems/score/processormask.h>
#include <rtems/score/scheduler.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup RTEMSTestFramework
 *
 * @{
 */

typedef enum {
	T_SCHEDULER_NOP,
	T_SCHEDULER_ADD_PROCESSOR,
	T_SCHEDULER_ANY,
	T_SCHEDULER_ASK_FOR_HELP,
	T_SCHEDULER_BLOCK,
	T_SCHEDULER_CANCEL_JOB,
	T_SCHEDULER_CLEAN_STICKY,
	T_SCHEDULER_INITIALIZE,
	T_SCHEDULER_MAKE_STICKY,
	T_SCHEDULER_MAP_PRIORITY,
	T_SCHEDULER_NODE_DESTROY,
	T_SCHEDULER_NODE_INITIALIZE,
	T_SCHEDULER_PIN,
	T_SCHEDULER_RECONSIDER_HELP_REQUEST,
	T_SCHEDULER_RELEASE_JOB,
	T_SCHEDULER_REMOVE_PROCESSOR,
	T_SCHEDULER_SCHEDULE,
	T_SCHEDULER_SET_AFFINITY,
	T_SCHEDULER_START_IDLE,
	T_SCHEDULER_UNBLOCK,
	T_SCHEDULER_UNMAP_PRIORITY,
	T_SCHEDULER_UNPIN,
	T_SCHEDULER_UPDATE_PRIORITY,
	T_SCHEDULER_WITHDRAW_NODE,
	T_SCHEDULER_YIELD
} T_scheduler_operation;

typedef struct {
	Thread_Control *executing;
	uint32_t cpu;
	T_time instant;
	T_scheduler_operation operation;
	Thread_Control *thread;
	Scheduler_Node *node;
	union {
		struct {
			Priority_Control in;
			Priority_Control out;
		} map_unmap_priority;
		struct {
			bool success;
		} ask_for_help;
		struct {
#ifdef RTEMS_SMP
			Thread_Scheduler_state next_state;
#else
			int next_state;
#endif
		} withdraw_node;
		struct {
			struct Per_CPU_Control *cpu;
		} pin_unpin;
		struct {
			Thread_Control *idle;
		} add_processor;
		struct {
			struct Per_CPU_Control *cpu;
			Thread_Control *idle;
		} remove_processor;
		struct {
			Priority_Node *priority;
			uint64_t deadline;
		} release_job;
		struct {
			Priority_Node *priority;
		} cancel_job;
		struct {
			Processor_mask affinity;
			Status_Control status;
		} set_affinity;
	};
} T_scheduler_event;

typedef struct {
	size_t recorded;
	size_t capacity;
	uint64_t operations;
} T_scheduler_header;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[T_ZERO_LENGTH_ARRAY];
} T_scheduler_log;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[2];
} T_scheduler_log_2;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[4];
} T_scheduler_log_4;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[10];
} T_scheduler_log_10;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[20];
} T_scheduler_log_20;

typedef struct {
	T_scheduler_header header;
	T_scheduler_event events[40];
} T_scheduler_log_40;

T_scheduler_log *T_scheduler_record(T_scheduler_log *);

T_scheduler_log *T_scheduler_record_2(T_scheduler_log_2 *);

T_scheduler_log *T_scheduler_record_4(T_scheduler_log_4 *);

T_scheduler_log *T_scheduler_record_10(T_scheduler_log_10 *);

T_scheduler_log *T_scheduler_record_20(T_scheduler_log_20 *);

T_scheduler_log *T_scheduler_record_40(T_scheduler_log_40 *);

typedef enum {
	T_SCHEDULER_BEFORE,
	T_SCHEDULER_AFTER
} T_scheduler_when;

typedef void (*T_scheduler_event_handler)(void *, const T_scheduler_event *,
    T_scheduler_when);

void T_scheduler_set_event_handler(T_scheduler_event_handler, void *);

extern const T_scheduler_event T_scheduler_event_null;

const T_scheduler_event *T_scheduler_next(T_scheduler_header *,
    T_scheduler_operation, size_t *);

const T_scheduler_event *T_scheduler_next_any(T_scheduler_header *,
    size_t *);

void T_scheduler_initialize(const Scheduler_Control *);

void T_scheduler_schedule(const Scheduler_Control *, Thread_Control *);

void T_scheduler_yield(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_block(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_unblock(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_update_priority(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

Priority_Control T_scheduler_map_priority(const Scheduler_Control *,
    Priority_Control);

Priority_Control T_scheduler_unmap_priority(const Scheduler_Control *,
    Priority_Control);

void T_scheduler_node_initialize(const Scheduler_Control *, Scheduler_Node *,
    Thread_Control *, Priority_Control);

void T_scheduler_node_destroy(const Scheduler_Control *, Scheduler_Node *);

void T_scheduler_release_job(const Scheduler_Control *, Thread_Control *,
    Priority_Node *, uint64_t, Thread_queue_Context *);

void T_scheduler_cancel_job(const Scheduler_Control *, Thread_Control *,
    Priority_Node *, Thread_queue_Context *);

void T_scheduler_start_idle(const Scheduler_Control *, Thread_Control *,
    struct Per_CPU_Control *);

#ifdef RTEMS_SMP
bool T_scheduler_ask_for_help(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_reconsider_help_request(const Scheduler_Control *,
    Thread_Control *, Scheduler_Node *);

void T_scheduler_withdraw_node(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *, Thread_Scheduler_state);

void T_scheduler_make_sticky(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_clean_sticky(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *);

void T_scheduler_pin(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *, struct Per_CPU_Control *);

void T_scheduler_unpin(const Scheduler_Control *, Thread_Control *,
    Scheduler_Node *, struct Per_CPU_Control *);

void T_scheduler_add_processor(const Scheduler_Control *, Thread_Control *);

Thread_Control *T_scheduler_remove_processor(const Scheduler_Control *,
    struct Per_CPU_Control *);

Status_Control T_scheduler_set_affinity(const Scheduler_Control *,
    Thread_Control *, Scheduler_Node *, const Processor_mask *);
#endif

#ifdef RTEMS_SMP
#define T_SCHEDULER_ENTRY_POINTS { T_scheduler_initialize, \
    T_scheduler_schedule, T_scheduler_yield, T_scheduler_block, \
    T_scheduler_unblock, T_scheduler_update_priority, \
    T_scheduler_map_priority, T_scheduler_unmap_priority, \
    T_scheduler_ask_for_help, T_scheduler_reconsider_help_request, \
    T_scheduler_withdraw_node, T_scheduler_make_sticky, \
    T_scheduler_clean_sticky, T_scheduler_pin, T_scheduler_unpin, \
    T_scheduler_add_processor, T_scheduler_remove_processor, \
    T_scheduler_node_initialize, T_scheduler_node_destroy, \
    T_scheduler_release_job, T_scheduler_cancel_job, \
    T_scheduler_start_idle, T_scheduler_set_affinity }
#else
#define T_SCHEDULER_ENTRY_POINTS { T_scheduler_initialize, \
    T_scheduler_schedule, T_scheduler_yield, T_scheduler_block, \
    T_scheduler_unblock, T_scheduler_update_priority, \
    T_scheduler_map_priority, T_scheduler_unmap_priority, \
    T_scheduler_node_initialize, T_scheduler_node_destroy, \
    T_scheduler_release_job, T_scheduler_cancel_job, \
    T_scheduler_start_idle }
#endif

extern const Scheduler_Operations T_scheduler_operations[];

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* _RTEMS_TEST_SCHEDULER_H */