shell的本质
taskA wait (“TaskB”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| typedef struct { RegValue rv; Descriptor ldt[3]; ushort ldtSelector; ushort tssSelector; void (*tmain)(); uint id; ushort current; ushort total; char name[16]; Queue wait; byte* stack; Event* event; } Task;
|
taskA移入taskB的等待队列
taskB结束后要将taskB的等待队列的任务取出来
功能函数
查找任务FindTaskByName
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| static Task* FindTaskByName(const char* name) { Task* ret = NULL; if( !StrCmp(name, "IdleTask", -1) ) { int i = 0; for(i=0; i<MAX_TASK_BUFF_NUM; i++) { TaskNode* tn = AddrOff(gTaskBuff, i); if( tn->task.id && StrCmp(tn->task.name, name, -1) ) { ret = &tn->task; break; } } } return ret; }
|
waitTask
根据名字找到目标任务后,将当前任务放入目标任务的等待队列中
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void WaitTask(const char* name) { Task* task = FindTaskByName(name); if( task ) { Event* evt = CreateEvent(TaskEvent, (uint)task, 0, 0); if( evt ) { EventSchedule(WAIT, evt); } } }
|
事件
事件产生:任务进入等待状态
事件销毁:任务进入可执行状态
当任务请求输入时(调用readkey()时)产生事件,任务进入等待
task模块根据事件描述执行具体的调度动作(调度进哪一个等待队列)
事件定义:触发事件在就绪状态和等待状态之间的切换的因素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| enum { NoneEvent, MutexEvent, KeyEvent, TaskEvent };
typedef struct { uint type; uint id; uint param1; uint param2; } Event;
Event* CreateEvent(uint type, uint id, uint param1, uint param2) { Event* ret = Malloc(sizeof(Event)); if( ret ) { ret->type = type; ret->id = id; ret->param1 = param1; ret->param2 = param2; } return ret; }
void DestroyEvent(Event* event) { Free(event); }
|
事件机制的设计
由于当前任务出现了事件,因此需要记录当前事件的信息并且将当前任务进入某个等待队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
void EventSchedule(uint action, Event* event) { switch(event->type) { case KeyEvent: KeySchedule(action, event); break; case TaskEvent: TaskSchedule(action, event); break; case MutexEvent: MutexSchedule(action, event); break; default: break; } }
static void TaskSchedule(uint action, Event* event) { Task* task = (Task*)event->id; if( action == NOTIFY ) { WaittingToReady(&task->wait); } else if( action == WAIT ) { WaitEvent(&task->wait, event); } }
static void MutexSchedule(uint action, Event* event) { Mutex* mutex = (Mutex*)event->id; if( action == NOTIFY ) { WaittingToReady(&mutex->wait); } else if( action == WAIT ) { WaitEvent(&mutex->wait, event); } }
static void WaitEvent(Queue* wait, Event* event) { gCTaskAddr->event = event; RunningToWaitting(wait); ScheduleNext(); }
|
task模块
根据事件执行调度,根据不同的事件进入不同等待队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void WaitTask(const char* name) { Task* task = FindTaskByName(name); if( task ) { Event* evt = CreateEvent(TaskEvent, (uint)task, 0, 0); if( evt ) { EventSchedule(WAIT, evt); } } }
|
mutex模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| static void DoWait(Mutex* mutex, uint* wait) { Event* evt = CreateEvent(MutexEvent, (uint)mutex, 0, 0); if( evt ) { *wait = 1; EventSchedule(WAIT, evt); } }
static void SysNormalEnter(Mutex* mutex, uint* wait) { if( mutex->lock ) { DoWait(mutex, wait); } else { mutex->lock = 1; *wait = 0; } }
|