Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
int
taskcreate(void (*fn)(void*), void *arg, uint stack)
{
	int id;
	Task *t;

   //fprintf(stderr,"taskcreate 1\n");
	t = taskalloc(fn, arg, stack);
   //fprintf(stderr,"taskcreate 2\n");
	taskcount++;
	id = t->id;
   //fprintf(stderr,"taskcreate 3\n");
	if(nalltask%64 == 0){
		alltask = (Task**) realloc(alltask, (nalltask+64)*sizeof(alltask[0]));
   //fprintf(stderr,"taskcreate 4\n");
		if(alltask == nil){
			fprint(2, "out of memory\n");
			abort();
		}
	}
   //fprintf(stderr,"taskcreate 5\n");
	t->alltaskslot = nalltask;
	alltask[nalltask++] = t;
   //fprintf(stderr,"taskcreate 6\n");
	taskready(t);
   //fprintf(stderr,"taskcreate 7\n");
	return id;
}
Ejemplo n.º 3
0
/*
	a->op is Recv: 从对应得Channel的发送队列随机取出一个Alt,
					并读取数据,Alt对应的Task可以进入就绪队列了
	a->op is Send: 将数据拷贝到Buffer中
 */
static void
altexec(Alt *a)
{
	int i;
	Altarray *ar;
	Alt *other;
	Channel *c;

	c = a->c;
	ar = chanarray(c, otherop(a->op));
	if(ar && ar->n){
		// 这里的逻辑目前看都是a->op == RECV才跑得到
		i = rand()%ar->n;
		other = ar->a[i];
		// a->v = other->v
		altcopy(a, other);
		// 将other从Channel的队列(接收队列)中删除
		altalldequeue(other->xalt);
		other->xalt[0].xalt = other;
		// Task重新进入就绪队列
		taskready(other->task);
	}else {
		// 将a->v的数据放到buffer里面
		altcopy(a, nil);
	}
}
Ejemplo n.º 4
0
// 使用函数 fn 创建一个新的协程, 并添加到协程队列
int
taskcreate(void (*fn)(void*), void *arg, uint stack)
{
	int id;
	Task *t;

    // 申请协程结构的空间以及初始化
	t = taskalloc(fn, arg, stack);
    // 当前协程数目 +1
	taskcount++;
	id = t->id;
    // 存储所有协程的数组是否需要扩容
    // 为什么是 nalltask % 64 == 0 是扩容的条件? 
    // 因为每次增加64,所以每当能整除的时候说明,空间用完
	if(nalltask%64 == 0){
		alltask = realloc(alltask, (nalltask+64)*sizeof(alltask[0]));
		if(alltask == nil){
			fprint(2, "out of memory\n");
			abort();
		}
	}

    // 放到数组尾部
	t->alltaskslot = nalltask;
	alltask[nalltask++] = t;

    // 协程状态设置为就绪, 可以进行调度
	taskready(t);
	return id;
}
Ejemplo n.º 5
0
void
fdtask(void *v)
{
    int i, ms;
    PollResult result;
    int rc = 0;
    
    rc = PollResult_init(POLL, &result);
    check(rc == 0, "Failed to initialize the poll result.");

    tasksystem();
    taskname("fdtask");

    for(;;){
        /* let everyone else run */
        while(taskyield() > 0)
            ;
        /* we're the only one runnable - poll for i/o */
        errno = 0;
        taskstate("poll");

        ms = next_task_sleeptime(500);

        if(SIGNALED) {
            for(i = 0; i < SuperPoll_active_hot(POLL); i++) {
                Task *target = (Task *)SuperPoll_data(POLL, i);
                if(target) taskready(target);
                SuperPoll_compact_down(POLL, i);
            }
        } else {
            rc = SuperPoll_poll(POLL, &result, ms);
            check(rc != -1, "SuperPoll failure, aborting.");

            for(i = 0; i < rc; i++) {
                taskready(result.hits[i].data); 
            }
        }

        wake_sleepers();
    }

    PollResult_clean(&result);
    taskexit(0);

error:
    taskexitall(1);
}
Ejemplo n.º 6
0
void
runlock(RWLock *l)
{
	Task *t;
	if (--l->readers == 0 && (t = l->wwaiting.head) != nil) {
		deltask(&l->wwaiting, t);
		l->writer = t;
		taskready(t);
	}
}
Ejemplo n.º 7
0
int
taskyield(void)
{
	int n;
	
	n = tasknswitch;
	taskready(taskrunning);
	taskstate("yield");
	taskswitch();
	return tasknswitch - n - 1;
}
Ejemplo n.º 8
0
int
taskyield(void)
{
	int n;
	
	n = tasknswitch;//用来计算自愿放弃协程后,到恢复所发生的切换次数
	taskready(taskrunning);//挂到taskrunqueue后面
	taskstate("yield");
	taskswitch();
	return tasknswitch - n - 1;
}
Ejemplo n.º 9
0
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);
	}
}
Ejemplo n.º 10
0
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);
    }
}
Ejemplo n.º 11
0
// 协程让出 cpu
int
taskyield(void)
{
	int n;
	
	n = tasknswitch;
    // 添加到就绪队列的尾部, 相当于让排在它后面的协程优先调度
	taskready(taskrunning);
    // 状态标识为 yield
	taskstate("yield");
    // 切换上下文
	taskswitch();
    // tasknswitch表示协程调度次数,出让到再次调用,两次相减就是出让的调度次数
	return tasknswitch - n - 1;
}
Ejemplo n.º 12
0
void fdtask(void *v)
{
    int i, ms;
    PollResult result;
    int rc = 0;
    FDTASK = taskself();
    
    rc = PollResult_init(POLL, &result);
    check(rc == 0, "Failed to initialize the poll result.");

    tasksystem();
    taskname("fdtask");

    for(;;){
        /* let everyone else run */
        while(taskyield() > 0)
            ;
        /* we're the only one runnable - poll for i/o */

        errno = 0;
        taskstate("poll");

        ms = next_task_sleeptime(500);

        if(task_was_signaled()) {
            fdtask_shutdown();
            task_clear_signal();
            break;
        } else {
            rc = SuperPoll_poll(POLL, &result, ms);
            check(rc != -1, "SuperPoll failure, aborting.");

            for(i = 0; i < rc; i++) {
                taskready(result.hits[i].data); 
            }

            wake_sleepers();
        }

    }

    PollResult_clean(&result);
    FDTASK = NULL;
    return;

error:
    taskexitall(1);
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
static void
altexec(Alt *a)
{
	int i;
	Altarray *ar;
	Alt *other;
	Channel *c;

	c = a->c;
	ar = chanarray(c, otherop(a->op));
	if(ar && ar->n){
		i = rand()%ar->n;
		other = ar->a[i];
		altcopy(a, other);
		altalldequeue(other->xalt);
		other->xalt[0].xalt = other;
		taskready(other->task);
	}else
		altcopy(a, nil);
}
Ejemplo n.º 15
0
int
taskcreate(void (*fn)(void*), void *arg, uint stack)
{
	int id;
	Task *t;

	t = taskalloc(fn, arg, stack);//初始化申请Task数据结构,设置堆栈内容等
	taskcount++;//当前OK的协程数目,不包括系统级别的协程
	id = t->id;
	if(nalltask%64 == 0){//一次申请64个槽位,只能往后放
		alltask = realloc(alltask, (nalltask+64)*sizeof(alltask[0]));
		if(alltask == nil){
			fprint(2, "out of memory\n");
			abort();
		}
	}
	t->alltaskslot = nalltask;
	alltask[nalltask++] = t;
	taskready(t);//加入taskrunqueue的运行队列
	return id;
}
Ejemplo n.º 16
0
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);
		}
	}
}
Ejemplo n.º 17
0
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);
		}
	}
}