2021-05-23 22:24:02 +08:00

154 lines
3.4 KiB
C

/*
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
* http://license.coscl.org.cn/MulanPSL
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v1 for more details.
*/
#pragma once
#include <common/registers.h>
#include <common/types.h>
#include <common/list.h>
#include <common/kprint.h>
#include <common/machine.h>
struct thread;
/* BUDGET represents the number of TICKs */
#define DEFAULT_BUDGET 2
#define TICK_MS 500
#define MAX_PRIO 255
#define MIN_PRIO 0
#define PRIO_NUM (MAX_PRIO + 1)
#define NO_AFF -1
/* Data structures */
#define STATE_STR_LEN 20
enum thread_state {
TS_INIT = 0,
TS_READY,
/* intermediate stat used by sched */
TS_INTER,
TS_RUNNING,
TS_EXIT,
/* waiting IPC or etc */
TS_WAITING,
/* waiting to be exited */
TS_EXITING,
};
#define TYPE_STR_LEN 20
enum thread_type {
TYPE_IDLE = 0,
/* ROOT thread has all cap, it is also a user thread */
TYPE_ROOT,
TYPE_USER,
TYPE_SHADOW,
TYPE_KERNEL,
TYPE_TESTS
};
typedef struct sched_cont {
u32 budget;
char pad[pad_to_cache_line(sizeof(u32))];
} sched_cont_t;
/* size in registers.h (to be used in asm) */
typedef struct arch_exec_cont {
u64 reg[REG_NUM];
} arch_exec_cont_t;
struct thread_ctx {
/* Executing Context */
arch_exec_cont_t ec;
/* Scheduling Context */
sched_cont_t *sc;
/* Thread Type */
u32 type;
/* Thread state */
u32 state;
/* Priority */
u32 prio;
/* SMP Affinity */
s32 affinity;
/* Current Assigned CPU */
u32 cpuid;
};
/* Debug functions */
void print_thread(struct thread *thread);
extern char thread_type[][TYPE_STR_LEN];
extern char thread_state[][STATE_STR_LEN];
void arch_idle_ctx_init(struct thread_ctx *idle_ctx, void (*func) (void));
u64 switch_context(void);
int sched_is_runnable(struct thread *target);
int sched_is_running(struct thread *target);
int switch_to_thread(struct thread *target);
/* Global-shared kernel data */
extern struct list_head ready_queue[PLAT_CPU_NUM][PRIO_NUM];
extern struct thread *current_threads[PLAT_CPU_NUM];
/* Indirect function call may downgrade performance */
struct sched_ops {
int (*sched_init) (void);
int (*sched) (void);
int (*sched_enqueue) (struct thread * thread);
int (*sched_dequeue) (struct thread * thread);
struct thread *(*sched_choose_thread) (void);
void (*sched_handle_timer_irq) (void);
/* Debug tools */
void (*sched_top) (void);
};
/* Provided Scheduling Policies */
extern struct sched_ops rr; /* Simple Round Robin */
/* Chosen Scheduling Policies */
extern struct sched_ops *cur_sched_ops;
int sched_init(struct sched_ops *sched_ops);
static inline int sched(void)
{
return cur_sched_ops->sched();
}
static inline int sched_enqueue(struct thread *thread)
{
return cur_sched_ops->sched_enqueue(thread);
}
static inline int sched_dequeue(struct thread *thread)
{
return cur_sched_ops->sched_dequeue(thread);
}
static inline struct thread *sched_choose_thread(void)
{
return cur_sched_ops->sched_choose_thread();
}
static inline void sched_handle_timer_irq(void)
{
cur_sched_ops->sched_handle_timer_irq();
}