void wunlock(RWLock *l) { Task *t; if(l->writer == nil){ fprint(2, "wunlock: not locked\n"); abort(); } l->writer = nil; if(l->readers != 0){ fprint(2, "wunlock: readers\n"); abort(); } while((t = l->rwaiting.head) != nil){ deltask(&l->rwaiting, t); l->readers++; taskready(t); } if(l->readers == 0 && (t = l->wwaiting.head) != nil){ deltask(&l->wwaiting, t); l->writer = t; taskready(t); } }
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); } } }
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); } } }
static void taskscheduler(void) { int i; Task *t; for (; ;) { if (taskcount == 0) exit(taskexitval); t = taskrunqueue.head; if (t == nil) { fprintf(stderr, "no runnable tasks! %d tasks stalled\n", taskcount); exit(1); } deltask(&taskrunqueue, t); t->ready = 0; taskrunning = t; tasknswitch++; contextswitch(&taskschedcontext, &t->context); taskrunning = nil; if (t->exiting) { if (!t->system) taskcount--; i = t->alltaskslot; alltask[i] = alltask[--nalltask]; alltask[i]->alltaskslot = i; free(t); } } }
void runlock(RWLock *l) { Task *t; if (--l->readers == 0 && (t = l->wwaiting.head) != nil) { deltask(&l->wwaiting, t); l->writer = t; taskready(t); } }
static inline void wake_sleepers() { Task *t; uvlong now = nsec(); while((t =sleeping.head) && now >= t->alarmtime){ deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } }
void qunlock(QLock *l) { Task *ready; if (l->owner == 0) { fprint(2, "qunlock: owner=0\n"); abort(); } if ((l->owner = ready = l->waiting.head) != nil) { deltask(&l->waiting, ready); taskready(ready); } }
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); } } }
static inline void fdtask_shutdown() { int i = 0; for(i = 0; i < SuperPoll_active_hot(POLL); i++) { SuperPoll_compact_down(POLL, i); } // move all our sleeping tasks over to the main runqueue Task *t = NULL; while((t = sleeping.head)){ deltask(&sleeping, t); tasksignal(t, task_was_signaled()); } }
static int _taskwakeup(Rendez *r, int all) { int i; Task *t; for (i = 0;; ++i) { if (i == 1 && !all) { break; } if ((t = r->waiting.head) == nil) { break; } deltask(&r->waiting, t); taskready(t); } return i; }
Task * queueup(Task * fel,Server * servers) // keep track of the task that gets in to the server and form one final queue { float currentT = 0; int remS = 64; Task * newQ = NULL; Task * currentQ0 = createdq(-1); Task * currentQ1 = createdq(-1); Task * queue = NULL; Task * temp = NULL; while(fel != NULL) { currentT = fel->artime; if(fel -> type == 0)//this is a dq event { remS++; servers = freeS(servers, currentT); while(currentQ0 != NULL) { temp = dequeue(currentQ0,remS); if (temp != NULL) { remS -= temp->nofstasks; servers = busyS(servers,temp,currentT); //set servers to work temp->timelq = currentT; queue = recordQ(queue,temp); mergedq(temp, fel ,currentT); deltask(temp); } else { break; } } while(currentQ1 != NULL) { temp = dequeue(currentQ1,remS); if (temp != NULL) { remS -= temp->nofstasks; servers = busyS(servers,temp,currentT); temp->timelq = currentT; queue = recordQ(queue,temp); mergedq(temp,fel,currentT); deltask(temp); } else { break; } } } else if (fel->type == 1)//if the head of the fel is a task { if(fel->nofstasks <= remS) { remS -= fel->nofstasks; servers = busyS(servers,fel,currentT); fel->timelq = currentT; queue = recordQ(queue,fel); mergedq(fel,fel,currentT); } else { newQ = copyQ(fel); if(fel->priority == 0) { currentQ0 = mergeFEL(currentQ0,newQ);//mergeFEL will return the head of currentQ } else { currentQ1 = mergeFEL(currentQ1,newQ); } } } temp = fel->next; deltask(fel); fel = temp; } task_destroy(findhead(currentQ0)); task_destroy(findhead(currentQ1)); return queue; }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); for(;;){ //fprintf(stderr,"pooling0\n"); /* let everyone else run */ taskyield(); //fprintf(stderr,"\n after yield %d\n", maysamYieldRet); //while(taskyield() > 0); /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); //Added by Maysam Yabandeh //taskname("fdtask(%d)",npollfd); if((t=sleeping.head) == nil) ms = -1; else{ /* sleep at most 5s */ now = nsec(); if(now >= t->alarmtime) ms = 0; else if(now+5*1000*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 5000; } //Added by Maysam Yabandeh //if (ms == -1 && maysamYieldRet == 0) ms = 0; if (ms == -1) ms = 0; //fprintf(stderr,"pooling ms is %d npollfd is %d\n", ms, npollfd); #ifndef USE_SHM if(poll(pollfd, npollfd, ms) < 0){ //fprintf(stderr,"pooling error\n"); if(errno == EINTR) continue; fprint(2, "poll: %s\n", strerror(errno)); taskexitall(0); } //fprintf(stderr,"pooling2\n"); /* wake up the guys who deserve it */ for(i=0; i<npollfd; i++){ while(i < npollfd && pollfd[i].revents){ //fprintf(stderr,"pooling3\n"); taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #else /* wake up the guys who deserve it */ //extern mpass::MessageEndPoint msg_end_point; mpass::MessageEndPoint *end_point = &mpass::msg_end_point; for(i=0; i<npollfd; i++){ int &fd = pollfd[i].fd; bool read = pollfd[i].events & POLLIN; mpass::Connection *conn = &end_point->conn_array[fd]; if ( (read && !conn->rcv_q->is_empty()) || (!read && !conn->snd_q->is_full()) ) { taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #endif //fprintf(stderr,"pooling4\n"); now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ //fprintf(stderr,"pooling5\n"); deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } } }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); struct epoll_event events[20000]; for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - epoll for i/o */ errno = 0; taskstate("epoll"); if(sleeping.head == nil && blocking.head == nil) ms = -1; else{ /* sleep at most 100ms */ now = nsec(); if (t) { if(now >= t->alarmtime) ms = 0; else if(now+500*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 500; }else{ ms = 500; } } int nevents; if((nevents = epoll_wait(epfd, events, 20000, ms)) < 0){ if(errno == EINTR) continue; fprint(2, "epoll: %s\n", strerror(errno)); taskexitall(0); } /* wake up the guys who deserve it */ for(i=0; i<nevents; i++){ //deleting it from blocking queue for (t = blocking.head; t!= nil && t!= events[i].data.ptr; t=t->next) ; if(t==events[i].data.ptr) deltask(&blocking,t); taskready((Task *)events[i].data.ptr); } now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } /*wake up the guys who are blocked */ while((t=blocking.head) && now >= t->alarmtime){ deltask(&blocking, t); if(!t->system && --blockingcounted == 0) taskcount--; taskready(t); } } }