Files
mango/include/socks/sched.h

178 lines
4.2 KiB
C
Raw Normal View History

#ifndef SOCKS_SCHED_H_
#define SOCKS_SCHED_H_
#include <socks/pmap.h>
#include <socks/locks.h>
#include <socks/queue.h>
#include <socks/object.h>
#include <socks/btree.h>
#include <socks/status.h>
#define TASK_NAME_MAX 64
#define PRIO_MAX 32
#define THREAD_KSTACK_ORDER VM_PAGE_4K
2023-03-20 20:41:39 +00:00
#ifdef __cplusplus
extern "C" {
#endif
enum task_state {
TASK_RUNNING,
TASK_STOPPED,
};
enum thread_state {
2023-03-19 20:35:48 +00:00
THREAD_READY = 1,
THREAD_SLEEPING = 2,
THREAD_STOPPED = 3,
};
enum thread_flags {
2023-03-19 20:35:48 +00:00
THREAD_F_NEED_RESCHED = 0x01u,
THREAD_F_NO_PREEMPT = 0x02u,
};
enum sched_priority {
PRIO_IDLE = 4,
PRIO_SUBNORMAL = 6,
PRIO_NORMAL = 10,
PRIO_SUPERNORMAL = 14,
PRIO_HIGH = 18,
PRIO_REALTIME = 24,
};
enum sched_mode {
/* used when calling from non-interrupt context.
threads that aren't in state THREAD_READY are
removed from the runqueue. */
SCHED_NORMAL = 0,
/* used when calling from interrupt context.
threads that aren't in state THREAD_READY are
still added to the runqueue. */
SCHED_IRQ = 1,
};
struct task {
struct task *t_parent;
unsigned int t_id;
enum task_state t_state;
char t_name[TASK_NAME_MAX];
pmap_t t_pmap;
struct btree_node t_tasklist;
struct queue t_threads;
struct queue t_children;
};
struct thread {
enum thread_state tr_state;
enum thread_flags tr_flags;
struct task *tr_parent;
unsigned int tr_id;
unsigned int tr_prio;
cycles_t tr_charge_period_start;
cycles_t tr_quantum_cycles, tr_quantum_target;
cycles_t tr_total_cycles;
uintptr_t tr_sp, tr_bp;
struct queue_entry tr_threads;
struct queue_entry tr_rqentry;
struct vm_page *tr_kstack;
};
struct runqueue {
struct queue rq_queues[PRIO_MAX];
uint32_t rq_readybits;
spin_lock_t rq_lock;
unsigned int rq_nthreads;
struct thread *rq_cur, *rq_idle;
};
struct timer {
struct queue_entry t_entry;
struct cpu_data *t_cpu;
struct thread *t_owner;
unsigned long t_expiry;
void(*t_callback)(struct timer *);
};
struct wait_item {
struct thread *w_thread;
struct queue_entry w_entry;
};
struct waitqueue {
struct queue wq_waiters;
spin_lock_t wq_lock;
};
extern kern_status_t sched_init(void);
extern void schedule(enum sched_mode mode);
extern void preempt_disable(void);
extern void preempt_enable(void);
extern void rq_init(struct runqueue *rq);
extern struct thread *rq_dequeue(struct runqueue *rq);
extern void rq_enqueue(struct runqueue *rq, struct thread *thr);
static inline void rq_lock(struct runqueue *rq, unsigned long *flags)
{
spin_lock_irqsave(&rq->rq_lock, flags);
}
static inline void rq_unlock(struct runqueue *rq, unsigned long flags)
{
spin_unlock_irqrestore(&rq->rq_lock, flags);
}
extern struct runqueue *cpu_rq(unsigned int cpu);
extern struct task *task_alloc(void);
static inline struct task *task_ref(struct task *task) { return (struct task *)object_data(object_ref(object_header(task))); }
static inline void task_deref(struct task *task) { object_deref(object_header(task)); }
extern struct task *task_from_pid(unsigned int pid);
extern struct task *kernel_task(void);
extern struct task *idle_task(void);
extern cycles_t default_quantum(void);
extern bool need_resched(void);
extern struct task *current_task(void);
extern struct thread *current_thread(void);
extern struct runqueue *select_rq_for_thread(struct thread *thr);
extern void schedule_thread_on_cpu(struct thread *thr);
extern void start_charge_period(void);
extern void end_charge_period(void);
static inline void task_lock_irqsave(struct task *task, unsigned long *flags)
{
object_lock(object_header(task), flags);
}
static inline void task_unlock_irqrestore(struct task *task, unsigned long flags)
{
object_unlock(object_header(task), flags);
}
extern struct thread *thread_alloc(void);
extern kern_status_t thread_init(struct thread *thr, uintptr_t ip);
extern int thread_priority(struct thread *thr);
extern void idle(void);
extern struct thread *create_kernel_thread(void(*fn)(void));
extern struct thread *create_idle_thread(void);
extern void add_timer(struct timer *timer);
extern void remove_timer(struct timer *timer);
extern unsigned long schedule_timeout(unsigned long clock_ticks);
extern unsigned long milli_sleep(unsigned long ms);
2023-03-20 20:41:39 +00:00
#ifdef __cplusplus
}
#endif
#endif