📄 sched.c
字号:
/* MShowTec - www.mshowtec.com
** msLinux sched.c ver1.0
** 20051221 lmjx create limiao@mshowtec.com
**
*/
#define MSLINUX_SCHED_C
#include "sched.h"
#include "errno.h"
#include "malloc.h"
#include "stack.h"
#include "fork.h"
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
#define LATCH (1193180/HZ)
struct task_struct task0 = INIT_TASK;
long volatile jiffies;
long startup_time;
struct task_struct *current = &(task0);
struct task_struct *next = &(task0);
struct task_struct *task[NR_TASKS] = { &(task0), };
void tic_delay(unsigned long tic)
{
int i = 0;
for(i=0;i<tic;i++){
__asm{nop};
}
}
void show_task (int nr, struct task_struct *p)
{
printk ("%d: pid=%d, state=", nr, p->pid);
switch(p->state){
case TASK_RUNNING:
printk("Running\r\n");
break;
case TASK_INTERRUPTIBLE:
printk("Interruptible\r\n");
break;
case TASK_UNINTERRUPTIBLE:
printk("Uninterruptible\r\n");
break;
case TASK_ZOMBIE:
printk("Zombie\r\n");
break;
default:
printk("State error\r\n");
break;
}
}
void show_stat(void)
{
int i;
printk("task stat:\r\n");
for (i = 0; i < NR_TASKS; i++)
if (task[i])
show_task (i,task[i]);
}
void schedule(void)
{
int i, j, c;
struct task_struct **p;
int irq_save;
irq_save = mslinux_save_disable_irq();
for (p = &LAST_TASK; p > &FIRST_TASK; --p)
if (*p)
{
if ((*p)->alarm && (*p)->alarm < jiffies)
{
(*p)->signal |= (1 << (SIGALRM - 1));
(*p)->alarm = 0;
}
if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
(*p)->state == TASK_INTERRUPTIBLE)
(*p)->state = TASK_RUNNING;
}
while (1)
{
c = -1;
j = 0;
i = NR_TASKS;
p = &task[NR_TASKS];
while (--i)
{
if (!*--p)
continue;
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
c = (*p)->counter, j = i;
}
if (c)
break;
for (p = &LAST_TASK; p > &FIRST_TASK; --p)
if (*p)
(*p)->counter = ((*p)->counter >> 1) + (*p)->priority;
}
next = task[j];
if(current == next){
goto sched_ret;
}
switch_to();
sched_ret:
mslinux_restore_irq(irq_save);
}
int sys_pause (void)
{
current->state = TASK_INTERRUPTIBLE;
schedule ();
return 0;
}
void sleep_on (struct task_struct **p)
{
struct task_struct *tmp;
if (!p)
return;
if (current == &(task0))
panic ("task[0] trying to sleep");
tmp = *p;
*p = current;
current->state = TASK_UNINTERRUPTIBLE;
schedule ();
if (tmp)
tmp->state = 0;
}
void interruptible_sleep_on (struct task_struct **p)
{
struct task_struct *tmp;
if (!p)
return;
if (current == &(task0))
panic ("task[0] trying to sleep");
tmp = *p;
*p = current;
repeat:
current->state = TASK_INTERRUPTIBLE;
schedule ();
if (*p && *p != current)
{
(**p).state = 0;
goto repeat;
}
*p = tmp;
if (tmp)
tmp->state = 0;
}
void wake_up (struct task_struct **p)
{
if (p && *p)
{
(**p).state = 0;
*p = NULL;
}
}
#define TIME_REQUESTS 64
static struct timer_list
{
long jiffies;
void (*fn) ();
struct timer_list *next;
}
timer_list[TIME_REQUESTS], *next_timer = NULL;
void add_timer (long jiffies, void (*fn) ())
{
struct timer_list *p;
unsigned short irq_save = 0;
if (!fn)
return;
irq_save = mslinux_save_disable_irq();
if (jiffies <= 0)
(fn) ();
else
{
for (p = timer_list; p < timer_list + TIME_REQUESTS; p++)
if (!p->fn)
break;
if (p >= timer_list + TIME_REQUESTS)
panic ("No more time requests free");
p->fn = fn;
p->jiffies = jiffies;
p->next = next_timer;
next_timer = p;
while (p->next && p->next->jiffies < p->jiffies)
{
p->jiffies -= p->next->jiffies;
fn = p->fn;
p->fn = p->next->fn;
p->next->fn = fn;
jiffies = p->jiffies;
p->jiffies = p->next->jiffies;
p->next->jiffies = jiffies;
p = p->next;
}
}
mslinux_restore_irq(irq_save);
}
unsigned long timer_resched_cnt = 0;
void do_timer ()
{
current->utime++;
if (next_timer)
{
next_timer->jiffies--;
while (next_timer && next_timer->jiffies <= 0)
{
void (*fn) ();
fn = next_timer->fn;
next_timer->fn = NULL;
next_timer = next_timer->next;
(fn) ();
}
}
if ((--current->counter) > 0)
return;
current->counter = 0;
timer_resched_cnt++;
}
int sys_alarm (long seconds)
{
int old = current->alarm;
if (old)
old = (old - jiffies) / HZ;
current->alarm = (seconds > 0) ? (jiffies + HZ * seconds) : 0;
return (old);
}
int sys_getpid (void)
{
return current->pid;
}
int sys_getppid (void)
{
return current->father;
}
int sys_getuid (void)
{
return current->uid;
}
int sys_geteuid (void)
{
return current->euid;
}
int sys_getgid (void)
{
return current->gid;
}
int sys_getegid (void)
{
return current->egid;
}
int sys_nice (long increment)
{
if (current->priority - increment > 0)
current->priority -= increment;
return 0;
}
int sys_setpriority(long priority)
{
if(priority)
current->priority = priority;
return priority;
}
int sys_setstack(long size)
{
int irq_save = 0;
long old_stack_top,new_stack_top,old_stack,new_stack;
void *p;
size = ALIGN4B(size) - 4 + 1;
if(size <= current->stack.L_Stack_SZ)
return -size;
p = malloc(size);
if(!p)
return -size;
((unsigned char*)p)[0] = 0x55;
new_stack_top = (long)p;
old_stack_top = current->stack.p_TopOfStack;
new_stack = new_stack_top+(size-current->stack.L_Stack_SZ);
memcpy((void*)(new_stack_top+(size-current->stack.L_Stack_SZ)),(void*)old_stack_top,current->stack.L_Stack_SZ);
irq_save = mslinux_save_disable_irq();
current->stack.p_SP = new_stack;
current->stack.p_TopOfStack = new_stack_top;
current->stack.L_Stack_SZ = size;
_sys_setstack(old_stack_top);
free((void*)old_stack_top);
mslinux_restore_irq(irq_save);
return size;
}
int sys_getpset() //get the current tcb set
{
int i = 0;
for(i = 0; i<NR_TASKS;i++){
if(task[i]->pid == current->pid)
return(i);
}
return -ERROR;
}
int sys_getdstpset(int pid)
{
int i = 0;
for(i = 0; i<NR_TASKS;i++){
if(task[i]->pid == pid)
return(i);
}
return -ERROR;
}
void sched_init (void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -