|
今天想了很久都想不明白,程序是怎么样用 setjump longjup 的
//
//
// task_create(...)里面有一个setjmp();而在schedule()有一对setjmp()
// longjmp()
//
// 谁能告诉我一下,,,以上setjmp(),longjmp()之间的程序流走向
//
// schedule()中的longjmp是返回到,task_create()中setjmp呢还是返
//
// 回到 sechedule()中的setjmp中的???????
//
//
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#define STACK_SIZE 1024
#define TASK_NUM 256
#define LINUX
#ifdef LINUX
#if !defined(JB_PC) && !defined(JB_SP)
#define JB_PC 5
#define JB_SP 4
#define PTR_MANGLE(var) asm ("xorl %%gs:0x18, %0" : "=r"(var) : "0" (var))
#else
#define PTR_MANGLE(var)
#endif
#define EIP buf[0].__jmpbuf[JB_PC]
#define ESP buf[0].__jmpbuf[JB_SP]
#else
#define EIP buf[5];
#define ESP buf[4];
#endif
typedef unsigned long ulong;
typedef long task_t;
typedef void (*task_func) (void *args);
typedef struct task_struct{
jmp_buf buf;
int used;
ulong stack[STACK_SIZE];
} task_struct;
static task_struct tasks[TASK_NUM]; // 定义TCB 任务控制块
static task_t current = 0;
int task_struct_init(void)
{
int i;
for(i = 0; i < TASK_NUM; i ++)
tasks.used = 0;
tasks[0].used = 1;// 创建第一个任务,在主函数中运行.
return 0;
}
int task_exit(void)
{
tasks[current].used = 0;
schedule();
}
// 获得处理ID pid
task_t gettid(void)
{
return current;
}
int task_create(task_t *pid, task_func func, void *args)
{
static int i;
// 遍历任务,找未用的
for(i = 0; i < TASK_NUM; i ++){
if(!tasks.used){
break;
}
}
// found none
if(i == TASK_NUM) return -1;
setjmp(tasks.buf); //任务的返回点 与longjmp结合吗??
tasks.stack[STACK_SIZE - 1] = (ulong)args;
tasks.ESP = (ulong)(tasks.stack + STACK_SIZE - 2);
PTR_MANGLE(tasks.ESP);
tasks.EIP = (ulong)func;
PTR_MANGLE(tasks.EIP);
tasks.used = 1;
if(pid != NULL){
*pid = i;
}
return 0;
}
// 选一个任务
// 运行到最后一个任务时,返回1
int schedule(void)
{
// 保存任务运行时间信息
if(setjmp(tasks[current].buf)){
return 1;
}
// select a active task to run
while(1){
current = (current + 1) % TASK_NUM;
if(tasks[current].used){
break;
}
}
// run the task
longjmp(tasks[current].buf, 1);
return 0;
}
void t1(const char *ptr)
{
int i;
char ch[128];
for(i = 0; i < 128; i ++){
ch = '0';
printf("task %d: %s.\n", gettid(), ptr);
schedule();
}
task_exit();
}
void t2(const char *ptr)
{
while(1){
printf("task %d: %s.\n", gettid(), ptr);
// 可加入新的任务;
task_create(NULL, (task_func)&t1, "one(in two)");
schedule();
}
}
void t3(const char *ptr)
{
char *buf;
while(1){
buf = (char*)malloc(256);
printf("task %d: %s.\n", gettid(), ptr);
// printf("Please input sth. :");
// scanf("%s", buf);
// printf("Your input is : %s\n", buf);
free(buf);
schedule();
}
}
int main(void)
{
task_struct_init();
task_create(NULL, (task_func)&t1, "one");
task_create(NULL, (task_func)&t2, "two");
task_create(NULL, (task_func)&t3, "three");
while(1){
printf("task %d: core.\n", gettid());
schedule();
}
return 0;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|