acrn-hypervisor/hypervisor/common/sched_prio.c

99 lines
2.3 KiB
C

/*
* Copyright (C) 2021 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <list.h>
#include <asm/per_cpu.h>
#include <schedule.h>
struct sched_prio_data {
/* keep list as the first item */
struct list_head list;
};
static int sched_prio_init(struct sched_control *ctl)
{
struct sched_prio_control *prio_ctl = &per_cpu(sched_prio_ctl, ctl->pcpu_id);
ASSERT(ctl->pcpu_id == get_pcpu_id(), "Init scheduler on wrong CPU!");
ctl->priv = prio_ctl;
INIT_LIST_HEAD(&prio_ctl->prio_queue);
return 0;
}
static void sched_prio_init_data(struct thread_object *obj)
{
struct sched_prio_data *data;
data = (struct sched_prio_data *)obj->data;
INIT_LIST_HEAD(&data->list);
}
static struct thread_object *sched_prio_pick_next(struct sched_control *ctl)
{
struct sched_prio_control *prio_ctl = (struct sched_prio_control *)ctl->priv;
struct thread_object *next = NULL;
if (!list_empty(&prio_ctl->prio_queue)) {
next = get_first_item(&prio_ctl->prio_queue, struct thread_object, data);
} else {
next = &get_cpu_var(idle);
}
return next;
}
static void prio_queue_add(struct thread_object *obj)
{
struct sched_prio_control *prio_ctl =
(struct sched_prio_control *)obj->sched_ctl->priv;
struct sched_prio_data *data = (struct sched_prio_data *)obj->data;
struct thread_object *iter_obj;
struct list_head *pos;
if (list_empty(&prio_ctl->prio_queue)) {
list_add(&data->list, &prio_ctl->prio_queue);
} else {
list_for_each(pos, &prio_ctl->prio_queue) {
iter_obj = container_of(pos, struct thread_object, data);
if (iter_obj->priority < obj->priority) {
list_add_node(&data->list, pos->prev, pos);
break;
}
}
if (list_empty(&data->list)) {
list_add_tail(&data->list, &prio_ctl->prio_queue);
}
}
}
static void prio_queue_remove(struct thread_object *obj)
{
struct sched_prio_data *data = (struct sched_prio_data *)obj->data;
list_del_init(&data->list);
}
static void sched_prio_sleep(struct thread_object *obj)
{
prio_queue_remove(obj);
}
static void sched_prio_wake(struct thread_object *obj)
{
prio_queue_add(obj);
}
struct acrn_scheduler sched_prio = {
.name = "sched_prio",
.init = sched_prio_init,
.init_data = sched_prio_init_data,
.pick_next = sched_prio_pick_next,
.sleep = sched_prio_sleep,
.wake = sched_prio_wake,
};