在user mode模拟进程调度
ddong 2005-09-11 03:48:26 小弟最近在学习linux的内核,写了一个模拟进程调度的程序,拿出来与各位讨论。让各位见笑了。
#include <conio.h>
#include <stdio.h>
#include <memory.h>
#define TASK_STACK_SIZE 4096 // 4k STACK per task
typedef struct task_struct{
int taskid;
int * esp;
}task_t;
typedef struct task_stack_struct{
int stack[ TASK_STACK_SIZE / sizeof(int) ];
}task_stack_t;
task_t task_list[3] = {0};
task_stack_t task_stack_list[2] = {0}; // task 0 need not a stack( use the system allocated one).
int cur_task = 0;
void __declspec(naked) switch_to_next( void )
{
__asm{
/* save current task */
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
lea ebx, task_list
mov ecx, cur_task
lea ebx, [ebx + ecx * 8 ]
mov [ebx].esp, esp ; stack pointer of current task
/* adjust index */
inc ecx
cmp ecx, 2
jle idx_ok
mov ecx, 0
idx_ok:
mov cur_task, ecx
/* switch to next proc and while the task will be switched */
lea ebx, task_list
lea ebx, [ebx + ecx * 8 ]
mov esp, [ebx].esp
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret
}
}
int proc( task_t * cur )
{
for ( ; ; )
{
printf("proc_%d is running\r\n", cur->taskid );
switch_to_next( );
}
}
int main(int argc, char* argv[])
{
// INIT the task 1. task 0 is the main and is not need to init.
task_list[1].taskid = 1;
task_list[1].esp = &task_stack_list[0].stack[TASK_STACK_SIZE / sizeof(int)];
--task_list[1].esp; *task_list[1].esp = (int)&task_list[1]; // param
--task_list[1].esp; *task_list[1].esp = 0; // return address
--task_list[1].esp; *task_list[1].esp = (int)proc; // return address
task_list[1].esp -= 7;
// INIT the task 2.
task_list[2].taskid = 2;
task_list[2].esp = &task_stack_list[1].stack[TASK_STACK_SIZE / sizeof(int)];
--task_list[2].esp; *task_list[2].esp = (int)&task_list[2]; // param
--task_list[2].esp; *task_list[2].esp = 0; // return address
--task_list[2].esp; *task_list[2].esp = (int)proc; // return address
task_list[2].esp -= 7;
while ( !_kbhit() )
{
printf("This is in main. press any key to exit!\r\n");
switch_to_next();
}
return 0;
}
这个程序是利用stack进行task切换,各个task有自己的堆栈。task0是main函数,它使用系统分配的stack,task1和task2分别有自己的4Kbytes stack.写的很粗糙,让各位见笑了。