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

📄 rt_monotonic_sched.c

📁 实时操作系统RT LINUX的源代码
💻 C
字号:
/* A simple rate-monotonic scheduler */#ifndef MODULE#   define MODULE#endif#include <linux/module.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/errno.h>#include <linux/malloc.h>#include <linux/kernel.h>#include <linux/cons.h>#ifdef MODVERSIONS#   include <linux/modversions.h>#endif#include <asm/system.h>#include <asm/rt_time.h>#include <asm/rt_irq.h>#include <asm/segment.h>#include "rt_sched.h"#include <linux/rtf.h>#ifdef DEBUG/* Process's state ( for debug purposes only ) */ #include "control.h"RTIME init_time = 0;#endif#define __STR(x) #x#define STR(x) __STR(x)#define PRINTAX \	"pushl %%eax\n\t" \	"pushl %%ebp\n\t" \	"pushl %%edi\n\t" \	"pushl %%esi\n\t" \	"pushl %%edx\n\t" \	"pushl %%ecx\n\t" \	"pushl %%ebx\n\t" \	"pushl %%eax\n\t" \	"call "SYMBOL_NAME_STR(conprn)"\n\t" \	"add $4, %%esp\n\t" \	"popl %%ebx\n\t \	popl %%ecx\n\t \	popl %%edx\n\t \	popl %%esi\n\t \	popl %%edi\n\t \	popl %%ebp\n\t \	popl %%eax\n\t"#define rt_switch_to(tsk) \	__asm__ __volatile__( \	"pushl %%eax\n\t" \	"pushl %%ebp\n\t" \	"pushl %%edi\n\t" \	"pushl %%esi\n\t" \	"pushl %%edx\n\t" \	"pushl %%ecx\n\t" \	"pushl %%ebx\n\t" \	"movl "SYMBOL_NAME_STR(rt_current)", %%edx\n\t" \	"cmpl $0, 4(%%edx)\n\t" \	"jz 25f\n\t" \	"sub $108,%%esp\n\t" \	"fsave (%%esp)\n\t" \"25:	pushl $1f\n\t" \	"movl %%esp, (%%edx)\n\t" \	"movl (%%ecx), %%esp\n\t" \	"movl %%ecx, "SYMBOL_NAME_STR(rt_current)"\n\t" \	"ret\n\t" \"1:	cmpl $0, 4(%%ecx)\n\t" \	"jz 26f\n\t" \	"frstor (%%esp)\n\t" \	"add $108,%%esp \n\t" \"26:	popl %%ebx\n\t" \	"popl %%ecx\n\t" \	"popl %%edx\n\t" \	"popl %%esi\n\t" \	"popl %%edi\n\t" \	"popl %%ebp\n\t" \	"popl %%eax\n\t" \	: /* no output */ \	: "c" (tsk) \	:"cx");/* RT_TASK *run_queue; */RT_TASK *rt_tasks;RT_TASK *rt_current;RT_TASK rt_linux_task;static int linux_irq_state;extern int rt_startup(void);__asm__(".align 4; .globl "SYMBOL_NAME_STR(rt_startup)"\n\t"		SYMBOL_NAME_STR(rt_startup)": iret");int rt_task_init(RT_TASK *task, void (*fn)(int), int data, int stack_size, 		 int id) /* Monotonic */ {	int *st;	long flags;	if (task->magic == RT_TASK_MAGIC) { 		return -EINVAL;	}	st = (int *) kmalloc(stack_size, GFP_KERNEL);		if (!st) {		return -ENOMEM;	}	/* task->priority = priority;    Don't use in monotonic scheduler */	task->magic = RT_TASK_MAGIC; 	task->state = RT_TASK_DORMANT; 	task->stack_bottom = st;	task->stack = st + stack_size / sizeof(int);	task->uses_fp = 0;	task->identifier = id; /* Monotonic */	*--(task->stack) = data;	*--(task->stack) = data;	*--(task->stack) = 0x200;	/* execute with interrupts enabled */	*--(task->stack) = KERNEL_CS;	*--(task->stack) = (int) fn;	*--(task->stack) = (int) rt_startup;	r_save_flags(flags);	r_cli();	task->next = rt_tasks;	rt_tasks = task;	r_restore_flags(flags);	return 0;}void rt_schedule(void){	RTIME now;	RTIME preemption_time;	RT_TASK *task;	RT_TASK *new_task;	RT_TASK *preemptor;	RTIME 	shortest_period;	int flags;	r_save_flags(flags);	r_cli();#ifdef DEBUG	now = rt_get_time();	if (rt_current->identifier != -1) {	    debug.state = EXEC;	    debug.id    = rt_current->identifier;	    debug.in    = init_time;	    debug.out   = now;	    rtf_put(DEBUG_FIFO, (char *) &debug,  sizeof(debug));	}#endif		for (task = rt_tasks; task; task = task->next) {		if ( task->state == RT_TASK_DELAYED && 		     task->resume_time < (now+10) ) {			task->state = RT_TASK_READY;		}	}	new_task = &rt_linux_task; /* begin rate-monotonic scheduling    */	shortest_period = rt_linux_task.period;      	for (task = rt_tasks; task; task = task->next) {	    if (task->state == RT_TASK_READY && 	        task->period < shortest_period) {		new_task = task;		shortest_period = task->period;	    }	} 	preemptor = 0;	preemption_time = RT_TIME_END;	for (task = rt_tasks; task; task = task->next) {	    if (task->state == RT_TASK_DELAYED && 	        task->resume_time < preemption_time) {	    	preemption_time = task->resume_time;	    	preemptor = task;	    }	}/* End of rate-monotonic scheduler */	if (preemptor) {		rt_set_timer(preemption_time);	} else {		rt_no_timer();	}	if (new_task == rt_current) {	  	r_restore_flags(flags);		return;	}	if (new_task == &rt_linux_task) {		SFIF = linux_irq_state;	} else if (rt_current == &rt_linux_task) {		linux_irq_state = SFIF;		SFIF = 0;	}#ifdef DEBUG	if (new_task->identifier != -1)	{	/* Monotonic scheduler */		init_time = now;	}#endif	new_task->state = RT_TASK_READY;	rt_switch_to(new_task);	r_restore_flags(flags);}#ifdef DEBUGstatic void rt_print_request(RT_TASK *task){	debug.state = SUSP;	debug.id   = task->identifier;	debug.in   = task->resume_time;	debug.out  = task->resume_time+task->period;	rtf_put(DEBUG_FIFO, (char *) &debug,  sizeof(debug));   } #endifint rt_task_delete(RT_TASK *task) {    RT_TASK *t;    int found = 0;    long flags;    r_save_flags(flags);    r_cli();    if (task->magic != RT_TASK_MAGIC) {	r_restore_flags(flags);	return -EINVAL;    }    if (task != rt_tasks) {	for (t = rt_tasks; t; t = t->next) {	    if (t->next == task) {		t->next = task->next;		found = 1;		break;	    }	}	if (!found) {	    r_restore_flags(flags);	    return -EINVAL;	}    } else 	rt_tasks = task->next;    task->magic = 0;    r_restore_flags(flags);    kfree(task->stack_bottom);    rt_schedule();    return 0;}int rt_task_suspend(RT_TASK *task){	task->state = RT_TASK_DORMANT;	rt_schedule();	return 0;}int rt_task_wakeup(RT_TASK *task){	task->state = RT_TASK_READY;	rt_schedule();	return 0;}int rt_task_wait(void){	long flags;	r_save_flags(flags);	r_cli();	rt_current->state = RT_TASK_DELAYED;	rt_current->resume_time += rt_current->period;#ifdef DEBUG	rt_print_request(rt_current);#endif	rt_schedule();	r_restore_flags(flags);	return 0;}/* Rate-monotonic scheduler ( set priority ) */int rt_task_make_periodic(RT_TASK *task, RTIME start_time, RTIME period){	long flags;	if (task->magic != RT_TASK_MAGIC) 		return -EINVAL;		r_save_flags(flags);	r_cli();	task->resume_time = start_time;	task->period = period;	task->state = RT_TASK_DELAYED;#ifdef DEBUG	rt_print_request(task);#endif 	r_restore_flags(flags);	rt_schedule();	return 0;}int init_module(void){#ifdef DEBUG	rtf_create(DEBUG_FIFO, 4000);#endif	rt_tasks = &rt_linux_task;	rt_current = &rt_linux_task;	rt_linux_task.priority = RT_LOWEST_PRIORITY;	rt_linux_task.period   = RT_BIGGEST_PERIOD;	rt_linux_task.next = 0;	rt_linux_task.identifier = -1; /* Monotonic */	rt_linux_task.state = RT_TASK_READY;	rt_request_timer(&rt_schedule);	return 0;}void cleanup_module(void){	RT_TASK *t;	RT_TASK *next_t;#ifdef DEBUG	rtf_destroy(DEBUG_FIFO);#endif	rt_free_timer();	for (t = rt_tasks; t; t = next_t) {		next_t = t->next;		if (t != &rt_linux_task) {			rt_task_delete(t);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -