/* 检查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; } } }
/* 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); } }
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); }
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); }
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; } } }
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; } }