Goto sanos source index
//
// sched.h
//
// Task scheduler
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// 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.
// 3. Neither the name of the project nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// 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 SCHED_H
#define SCHED_H
typedef void (*threadproc_t)(void *arg);
typedef void (*dpcproc_t)(void *arg);
typedef void (*taskproc_t)(void *arg);
//#define NOPREEMPTION
#define DEFAULT_QUANTUM 36
#define QUANTUM_UNITS_PER_TICK 3
#define THREAD_PRIORITY_LEVELS 32
#define PAGES_PER_TCB 2
#define TCBSIZE (PAGES_PER_TCB * PAGESIZE)
#define TCBMASK (~(TCBSIZE - 1))
#define TCBESP (TCBSIZE - 4)
#define DPC_QUEUED_BIT 0
#define DPC_EXECUTING_BIT 1
#define DPC_NORAND_BIT 2
#define DPC_QUEUED (1 << DPC_QUEUED_BIT)
#define DPC_EXECUTING (1 << DPC_EXECUTING_BIT)
#define DPC_NORAND (1 << DPC_NORAND_BIT)
#define TASK_QUEUE_ACTIVE 1
#define TASK_QUEUE_ACTIVE_TASK_INVALID 2
#define TASK_QUEUED 1
#define TASK_EXECUTING 2
struct tcb {
struct thread thread;
unsigned long stack[(TCBSIZE - sizeof(struct thread)) / sizeof(unsigned long) - 1];
unsigned long *esp;
};
struct dpc {
dpcproc_t proc;
void *arg;
struct dpc *next;
int flags;
};
struct task {
taskproc_t proc;
void *arg;
struct task *next;
int flags;
};
struct task_queue {
struct task *head;
struct task *tail;
struct thread *thread;
int maxsize;
int size;
int flags;
};
struct kernel_context {
unsigned long esi, edi;
unsigned long ebx, ebp;
unsigned long eip;
char stack[0];
};
extern struct thread *idlethread;
extern struct thread *threadlist;
extern struct task_queue sys_task_queue;
extern struct dpc *dpc_queue_head;
extern struct dpc *dpc_queue_tail;
extern int in_dpc;
extern int preempt;
extern unsigned long dpc_time;
#if 0
__inline __declspec(naked) struct thread *self() {
__asm {
mov eax, esp;
and eax, TCBMASK
ret
}
}
#endif
#if 0
__inline struct thread *self() {
unsigned long stkvar;
return (struct thread *) (((unsigned long) &stkvar) & TCBMASK);
}
#endif
struct thread *self();
void mark_thread_running();
krnlapi void mark_thread_ready(struct thread *t, int charge, int boost);
krnlapi void enter_wait(int reason);
krnlapi int enter_alertable_wait(int reason);
krnlapi int interrupt_thread(struct thread *t);
krnlapi struct thread *create_kernel_thread(threadproc_t startaddr, void *arg, int priority, char *name);
int create_user_thread(void *entrypoint, unsigned long stacksize, char *name, struct thread **retval);
int init_user_thread(struct thread *t, void *entrypoint);
int allocate_user_stack(struct thread *t, unsigned long stack_reserve, unsigned long stack_commit);
int destroy_thread(struct thread *t);
struct thread *get_thread(tid_t tid);
int suspend_thread(struct thread *t);
int resume_thread(struct thread *t);
void terminate_thread(int exitcode);
void suspend_all_user_threads();
int schedule_alarm(unsigned int seconds);
int get_thread_priority(struct thread *t);
int set_thread_priority(struct thread *t, int priority);
int get_thread_times(struct thread *t, struct tms *tms);
krnlapi int init_task_queue(struct task_queue *tq, int priority, int maxsize, char *name);
krnlapi void init_task(struct task *task);
krnlapi int queue_task(struct task_queue *tq, struct task *task, taskproc_t proc, void *arg);
krnlapi void init_dpc(struct dpc *dpc);
krnlapi void queue_dpc(struct dpc *dpc, dpcproc_t proc, void *arg);
krnlapi void queue_irq_dpc(struct dpc *dpc, dpcproc_t proc, void *arg);
krnlapi void add_idle_task(struct task *task, taskproc_t proc, void *arg);
void idle_task();
krnlapi void yield();
void dispatch_dpc_queue();
void preempt_thread();
krnlapi void dispatch();
krnlapi int system_idle();
void init_sched();
__inline void check_dpc_queue() {
if (dpc_queue_head) dispatch_dpc_queue();
}
__inline void check_preempt() {
#ifndef NOPREEMPTION
if (preempt) preempt_thread();
#endif
}
__inline int signals_ready(struct thread *t) {
return t->pending_signals & ~t->blocked_signals;
}
#endif