Beispiel #1
0
static void
taskscheduler(void)
{//协程调度函数
	int i;
	Task *t;

	taskdebug("scheduler enter");
	for(;;){
		if(taskcount == 0)
			exit(taskexitval);
		t = taskrunqueue.head;//从头部开始唤起
		if(t == nil){
			fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount);
			exit(1);
		}
		deltask(&taskrunqueue, t);//从待调度链表中移出来,调度它运行
		t->ready = 0;
		taskrunning = t;//标记正在执行的协程
		tasknswitch++;
		taskdebug("run %d (%s)", t->id, t->name);
		contextswitch(&taskschedcontext, &t->context);//真正进行上下文切换,这样就切换到了其他协程运行,比如taskmainstart
//print("back in scheduler\n");
		taskrunning = nil;//把刚刚被切换的协程的指向改为空。
		if(t->exiting){
			if(!t->system)
				taskcount--;
			i = t->alltaskslot;
			alltask[i] = alltask[--nalltask];
			alltask[i]->alltaskslot = i;
			free(t);
		}
	}
}
Beispiel #2
0
static void
taskscheduler(void)
{
	int i;
	Task *t;

	taskdebug("scheduler enter");
	for(;;){
		if(taskcount == 0)
			exit(taskexitval);
		t = taskrunqueue.head;
		if(t == nil){
			fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount);
			exit(1);
		}
		deltask(&taskrunqueue, t);
		t->ready = 0;
		taskrunning = t;
		tasknswitch++;
		taskdebug("run %d (%s)", t->id, t->name);
		contextswitch(&taskschedcontext, &t->context);
//print("back in scheduler\n");
		taskrunning = (Task*) nil;
		if(t->exiting){
			if(!t->system)
				taskcount--;
			i = t->alltaskslot;
			alltask[i] = alltask[--nalltask];
			alltask[i]->alltaskslot = i;
			free(t);
		}
	}
}
Beispiel #3
0
static void
taskscheduler(void)
{
	int i;
	Task *t;

	taskdebug("scheduler enter");
	for(;;){
        // 当前除了系统协程外没有其他协程, 退出
		if(taskcount == 0)
			exit(taskexitval);

        // 处理的顺序是 FIFO
		t = taskrunqueue.head;
		if(t == nil){
			fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount);
			exit(1);
		}
        // 从就绪队列里面去掉这个协程
		deltask(&taskrunqueue, t);
		t->ready = 0;

        // 把拿出来的就绪任务设置为当前正在执行的任务 
		taskrunning = t;
        // 协程调度计数 +1
		tasknswitch++;
		taskdebug("run %d (%s)", t->id, t->name);

        // 切换到刚拿到的协程, 调度的核心
        // 使用 taskschedcontext 保留老的堆栈状态, 把 t->context 设置为新的执行上下文
        // 后面通过 taskswitch 切换回调度协程
		contextswitch(&taskschedcontext, &t->context);
//print("back in scheduler\n");
		taskrunning = nil;

		if(t->exiting){ // 协程执行完退出
            // 系统协程不计数
			if(!t->system)
				taskcount--;

            // 把数组中最后一个任务放到要删除的任务的位置
            // 这里判断一下当前任务是不是已经在数据尾部会更加优雅?
			i = t->alltaskslot;
			alltask[i] = alltask[--nalltask];
			alltask[i]->alltaskslot = i;
            // 释放任务
			free(t);
		}
	}
}