Beispiel #1
0
int mill_choose_wait(void) {
    struct mill_choose *uc = &mill_running->u_choose;
    struct mill_slist_item *it;
    struct mill_clause *cl = NULL;

    /* If there are clauses that are immediately available
       randomly choose one of them. */
    if(uc->available > 0) {
        int chosen = uc->available == 1 ? 0 : (int)(random() % (uc->available));
        for(it = mill_slist_begin(&uc->clauses); it; it = mill_slist_next(it)) {
            cl = mill_cont(it, struct mill_clause, chitem);
            if(!cl->available)
                continue;
            if(!chosen)
                break;
            --chosen;
        }
        struct mill_chan *ch = mill_getchan(cl->ep);
        if(cl->ep->type == MILL_SENDER)
            mill_enqueue(ch, cl->val);
        else
            mill_dequeue(ch, mill_valbuf(cl->cr, ch->sz));
        mill_resume(mill_running, cl->idx);
        return mill_suspend();
    }
Beispiel #2
0
/* Unblock a coroutine blocked in mill_choose_wait() function.
   It also cleans up the associated clause list. */
static void mill_choose_unblock(struct mill_clause *cl) {
    struct mill_slist_item *it;
    struct mill_clause *itcl;
    for(it = mill_slist_begin(&cl->cr->u_choose.clauses);
          it; it = mill_slist_next(it)) {
        itcl = mill_cont(it, struct mill_clause, chitem);
        if(!itcl->used)
            continue;
        mill_list_erase(&itcl->ep->clauses, &itcl->epitem);
    }
    mill_resume(cl->cr, cl->idx);
}
Beispiel #3
0
void goredump(void) {
    char buf[256];
    char idbuf[10];

    fprintf(stderr,
        "\nCOROUTINE  state                                      "
        "current                                  created\n");
    fprintf(stderr,
        "----------------------------------------------------------------------"
        "--------------------------------------------------\n");
    struct mill_list_item *it;
    for(it = mill_list_begin(&mill_all_crs); it; it = mill_list_next(it)) {
        struct mill_cr *cr = mill_cont(it, struct mill_cr, debug.item);
        switch(cr->state) {
        case MILL_READY:
            sprintf(buf, "%s", mill_running == cr ? "RUNNING" : "ready");
            break;
        case MILL_MSLEEP:
            sprintf(buf, "msleep()");
            break;
        case MILL_FDWAIT:
            sprintf(buf, "fdwait(%d)", -1);
            break;
        case MILL_CHR:
        case MILL_CHS:
        case MILL_CHOOSE:
            {
                int pos = 0;
                if(cr->state == MILL_CHR)
                    pos += sprintf(&buf[pos], "chr(");
                else if(cr->state == MILL_CHS)
                    pos += sprintf(&buf[pos], "chs(");
                else
                    pos += sprintf(&buf[pos], "choose(");
                int first = 1;
                struct mill_slist_item *it;
                for(it = mill_slist_begin(&cr->u_choose.clauses); it;
                      it = mill_slist_next(it)) {
                if(first)
                    first = 0;
                else
                    pos += sprintf(&buf[pos], ",");
                pos += sprintf(&buf[pos], "<%d>", mill_getchan(
                        mill_cont(it, struct mill_clause,
                        chitem)->ep)->debug.id);
            }
            sprintf(&buf[pos], ")");
            }
            break;
        default:
            assert(0);
        }
        snprintf(idbuf, sizeof(idbuf), "{%d}", (int)cr->debug.id);
        fprintf(stderr, "%-8s   %-42s %-40s %s\n",
            idbuf,
            buf,
            cr == mill_running ? "---" : cr->debug.current,
            cr->debug.created ? cr->debug.created : "<main>");
    }
    fprintf(stderr,"\n");

    if(mill_list_empty(&mill_all_chans))
        return;
    fprintf(stderr,
        "CHANNEL  msgs/max    senders/receivers                          "
        "refs  done  created\n");
    fprintf(stderr,
        "----------------------------------------------------------------------"
        "--------------------------------------------------\n");
    for(it = mill_list_begin(&mill_all_chans); it; it = mill_list_next(it)) {
        struct mill_chan *ch = mill_cont(it, struct mill_chan, debug.item);
        snprintf(idbuf, sizeof(idbuf), "<%d>", (int)ch->debug.id);
        sprintf(buf, "%d/%d",
            (int)ch->items,
            (int)ch->bufsz);
        fprintf(stderr, "%-8s %-11s ",
            idbuf,
            buf);
        int pos;
        struct mill_list *clauselist;
        if(!mill_list_empty(&ch->sender.clauses)) {
            pos = sprintf(buf, "s:");
            clauselist = &ch->sender.clauses;
        }
        else if(!mill_list_empty(&ch->receiver.clauses)) {
            pos = sprintf(buf, "r:");
            clauselist = &ch->receiver.clauses;
        }
        else {
            sprintf(buf, " ");
            clauselist = NULL;
        }
        struct mill_clause *cl = NULL;
        if(clauselist)
            cl = mill_cont(mill_list_begin(clauselist),
                struct mill_clause, epitem);
        int first = 1;
        while(cl) {
            if(first)
                first = 0;
            else
                pos += sprintf(&buf[pos], ",");
            pos += sprintf(&buf[pos], "{%d}", (int)cl->cr->debug.id);
            cl = mill_cont(mill_list_next(&cl->epitem),
                struct mill_clause, epitem);
        }
        fprintf(stderr, "%-42s %-5d %-5s %s\n",
            buf,
            (int)ch->refcount,
            ch->done ? "yes" : "no",
            ch->debug.created);
    }
    fprintf(stderr,"\n");
}