Beispiel #1
0
/* 检查Alt a是否可以被执行
 */
static int
altcanexec(Alt *a)
{
	Altarray *ar;
	Channel *c;

	if(a->op == CHANNOP)
		return 0;
	c = a->c;
	if(c->bufsize == 0){	// 如果bufsize为0,则是通过发送接收队列共享数据的
		// 获取发送or接收队列
		ar = chanarray(c, otherop(a->op));
		return ar && ar->n;
	}else{
		switch(a->op){
		default:
			return 0;
		case CHANSND:
			// 如果是发送的情况,查看buffer还有没有空间了
			return c->nbuf < c->bufsize;
		case CHANRCV:
			// 如果是接收的情况,查看buffer还有没有数据
			return c->nbuf > 0;
		}
	}
}
Beispiel #2
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);
	}
}
Beispiel #3
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);
}
Beispiel #4
0
static void alt_exec(FIBER_ALT *a)
{
	FIBER_ALT_ARRAY *ar;
	FIBER_ALT *other;
	ACL_CHANNEL *c;
	int i;

	c = a->c;
	ar = channel_array(c, otherop(a->op));

	if (ar && ar->n) {
		i = rand() % ar->n;
		other = ar->a[i];
		alt_copy(a, other);
		alt_all_dequeue(other->xalt);
		other->xalt[0].xalt = other;

		acl_fiber_ready(other->fiber);
	 } else
		alt_copy(a, NULL);
}
Beispiel #5
0
static int
altcanexec(Alt *a)
{
	Altarray *ar;
	Channel *c;

	if(a->op == CHANNOP)
		return 0;
	c = a->c;
	if(c->bufsize == 0){
		ar = chanarray(c, otherop(a->op));
		return ar && ar->n;
	}else{
		switch(a->op){
		default:
			return 0;
		case CHANSND:
			return c->nbuf < c->bufsize;
		case CHANRCV:
			return c->nbuf > 0;
		}
	}
}
Beispiel #6
0
static int alt_can_exec(FIBER_ALT *a)
{
	FIBER_ALT_ARRAY *ar;
	ACL_CHANNEL *c;

	if (a->op == CHANNOP)
		return 0;

	c = a->c;
	if (c->bufsize == 0) {
		ar = channel_array(c, otherop(a->op));
		return ar && ar->n;
	}

	switch (a->op) {
		default:
			return 0;
		case CHANSND:
			return c->nbuf < c->bufsize;
		case CHANRCV:
			return c->nbuf > 0;
	}
}