⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched.c

📁 msLinux v1.0 可以在arm ads 下仿真运行的linux
💻 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 + -