elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elks
/
kernel
/
sched.c
File editor
/* * kernel/sched.c * (C) 1995 Chad Page * * This is the main scheduler - hopefully simpler than Linux's at present. */ #include <linuxmt/kernel.h> #include <linuxmt/sched.h> #include <linuxmt/init.h> #include <linuxmt/timer.h> #include <linuxmt/string.h> #include <linuxmt/trace.h> #include <linuxmt/debug.h> #include <arch/irq.h> struct task_struct *task; /* dynamically allocated task array */ struct task_struct *idle_task; /* NOTE: valid only thru k_stack[IDLESTACK_BYTES/2] */ struct task_struct *current; struct task_struct *previous; int max_tasks = MAX_TASKS; void add_to_runqueue(register struct task_struct *p) { #if UNUSED if (p->next_run || p->prev_run) panic("task already add_to_runq\n"); if (!idle_task->prev_run || !idle_task->next_run) panic("idle add_to_runq"); #endif (p->prev_run = idle_task->prev_run)->next_run = p; p->next_run = idle_task; idle_task->prev_run = p; } static void del_from_runqueue(register struct task_struct *p) { #if UNUSED if (!p->next_run || !p->prev_run) panic("delrunq %d,%d", p->pid, p->state); /* task not on run queue */ if (p == idle_task) panic("delrunq idle"); /* trying to sleep idle task */ #endif (p->next_run->prev_run = p->prev_run)->next_run = p->next_run; p->next_run = p->prev_run = NULL; } static void process_timeout(int __data) { struct task_struct *p = (struct task_struct *) __data; debug_sched("sched: timeout %d\n", p->pid); p->timeout = 0UL; wake_up_process(p); } /* * Schedule a task. On entry current is the task, which will * vanish quietly for a while and someone elses thread will return * from here. */ void schedule(void) { struct task_struct *prev; struct task_struct *next; jiff_t timeout = 0UL; struct timer_list timer; prev = current; #ifdef CHECK_SCHED if (intr_count > 1) { /* neither user nor idle task was running */ /* Taking a timer IRQ during another IRQ or while in kernel space is * quite legal. We just dont switch then */ panic("sched from int\n"); } /* Disallow rescheduling during startup when idle task is the only task */ if ((int)last_pid <= 0) { printk("SCHED at startup\n"); return; } #endif /* We have to let a task exit! */ if (prev->state == TASK_EXITING) return; clr_irq(); if (prev->state == TASK_INTERRUPTIBLE) { if (prev->signal || (prev->timeout && (prev->timeout <= jiffies))) { prev->timeout = 0UL; prev->state = TASK_RUNNING; } else { timeout = prev->timeout; } } /* Choose a task to run next */ next = prev->next_run; if (prev->state != TASK_RUNNING) del_from_runqueue(prev); if (next == idle_task) next = next->next_run; set_irq(); if (next != prev) { if (timeout) { timer.tl_expires = timeout; timer.tl_data = (int) prev; timer.tl_function = process_timeout; add_timer(&timer); } previous = prev; current = next; debug_sched("sched: %P\n"); tswitch(); /* Won't return for a new task */ if (timeout) { del_timer(&timer); } } else if (current->pid) debug_sched("resched: %P prevstate %d\n", prev->state); } static struct timer_list *next_timer; void add_timer(struct timer_list * timer) { struct timer_list **p; flag_t flags; timer->tl_next = NULL; p = &next_timer; save_flags(flags); clr_irq(); while (*p) { if ((*p)->tl_expires > timer->tl_expires) { timer->tl_next = *p; break; } p = &(*p)->tl_next; } *p = timer; restore_flags(flags); } int del_timer(struct timer_list * timer) { struct timer_list **p; flag_t flags; p = &next_timer; save_flags(flags); clr_irq(); while (*p) { if (*p == timer) { *p = timer->tl_next; restore_flags(flags); return 1; } p = &(*p)->tl_next; } restore_flags(flags); return 0; } void run_timer_list(void) { struct timer_list *timer; clr_irq(); while ((timer = next_timer) && timer->tl_expires <= jiffies) { del_timer(timer); set_irq(); timer->tl_function(timer->tl_data); clr_irq(); } set_irq(); } void INITPROC sched_init(void) { struct task_struct *t = &task[max_tasks]; /* * Mark tasks 0-(max_tasks-1) as not in use. */ do { (--t)->state = TASK_UNUSED; } while (t > task); /* * Now create task 0 to be ourself. */ t = idle_task; t->state = TASK_RUNNING; t->next_run = t->prev_run = t; //memset(t->t_kstack, 0xff, IDLESTACK_BYTES); /* for debugging idle stack size */ t->kstack_magic = KSTACK_MAGIC; current = t; next_task_slot = task; task_slots_unused = max_tasks; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history