/* Wait for events from a file descriptor, with an optional timeout. */ int mill_fdwait(int fd, int events, int64_t deadline, const char *current) { /* If required, start waiting for the timeout. */ if(deadline >= 0) { mill_running->u_fdwait.expiry = deadline; /* Move the timer into the right place in the ordered list of existing timers. TODO: This is an O(n) operation! */ struct mill_list_item *it = mill_list_begin(&mill_timers); while(it) { struct mill_fdwait *timer = mill_cont(it, struct mill_fdwait, item); /* If multiple timers expire at the same momemt they will be fired in the order they were created in (> rather than >=). */ if(timer->expiry > mill_running->u_fdwait.expiry) break; it = mill_list_next(it); } mill_list_insert(&mill_timers, &mill_running->u_fdwait.item, it); }
int mill_timer_fire(void) { /* Avoid getting current time if there are no timers anyway. */ if(mill_list_empty(&mill_timers)) return 0; int64_t nw = now(); int fired = 0; while(!mill_list_empty(&mill_timers)) { struct mill_timer *tm = mill_cont( mill_list_begin(&mill_timers), struct mill_timer, item); if(tm->expiry > nw) break; mill_list_erase(&mill_timers, mill_list_begin(&mill_timers)); if(tm->callback) tm->callback(tm); fired = 1; } return fired; }
void mill_timer_add(struct mill_timer *timer, int64_t deadline, mill_timer_callback callback) { mill_assert(deadline >= 0); timer->expiry = deadline; timer->callback = callback; /* Move the timer into the right place in the ordered list of existing timers. TODO: This is an O(n) operation! */ struct mill_list_item *it = mill_list_begin(&mill_timers); while(it) { struct mill_timer *tm = mill_cont(it, struct mill_timer, item); /* If multiple timers expire at the same momemt they will be fired in the order they were created in (> rather than >=). */ if(tm->expiry > timer->expiry) break; it = mill_list_next(it); } mill_list_insert(&mill_timers, &timer->item, it); }
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"); }