From: Fredrik Tolf Date: Sat, 31 Dec 2016 17:53:33 +0000 (+0100) Subject: Merge branch 'master' into timeheap X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=commitdiff_plain;h=bcad6b0c48d516ddc920b52f06083ceaa242e1ca Merge branch 'master' into timeheap Conflicts: lib/mtio-epoll.c --- bcad6b0c48d516ddc920b52f06083ceaa242e1ca diff --cc lib/mtio-epoll.c index 2a25992,af7cd27..3082eaf --- a/lib/mtio-epoll.c +++ b/lib/mtio-epoll.c @@@ -37,8 -37,7 +37,8 @@@ static struct blocker *blockers struct blocker { struct blocker *n, *p, *n2, *p2; int fd, reg; - int ev; + int ev, rev, id; + int thpos; time_t to; struct muth *th; }; @@@ -136,87 -129,19 +136,82 @@@ static void remfd(struct blocker *bl bl->reg = 0; } +static void thraise(struct timeentry ent, int n) +{ + int p; + + while(n > 0) { + p = (n - 1) >> 1; + if(timeheap.b[p].to <= ent.to) + break; + timeheap.b[n] = timeheap.b[p]; + timeheap.b[n].bl->thpos = n; + n = p; + } + timeheap.b[n] = ent; + ent.bl->thpos = n; +} + +static void thlower(struct timeentry ent, int n) +{ + int c; + + while(1) { + c = (n << 1) + 1; + if(c >= timeheap.d) + break; + if((c + 1 < timeheap.d) && (timeheap.b[c + 1].to < timeheap.b[c].to)) + c = c + 1; + if(timeheap.b[c].to > ent.to) + break; + timeheap.b[n] = timeheap.b[c]; + timeheap.b[n].bl->thpos = n; + n = c; + } + timeheap.b[n] = ent; + ent.bl->thpos = n; +} + +static void addtimeout(struct blocker *bl, time_t to) +{ + sizebuf(timeheap, ++timeheap.d); + thraise((struct timeentry){.to = to, .bl = bl}, timeheap.d - 1); +} + +static void deltimeout(struct blocker *bl) +{ + struct timeentry ent; + int n; + + if(bl->thpos == timeheap.d - 1) { + timeheap.d--; + return; + } + n = bl->thpos; + ent = timeheap.b[--timeheap.d]; + if((n > 0) && (timeheap.b[(n - 1) >> 1].to > ent.to)) + thraise(ent, n); + else + thlower(ent, n); +} + - int block(int fd, int ev, time_t to) + static int addblock(struct blocker *bl) { - struct blocker *bl; - int rv; - - omalloc(bl); - bl->fd = fd; - bl->ev = ev; - bl->th = current; - if((epfd >= 0) && regfd(bl)) { - free(bl); + if((epfd >= 0) && regfd(bl)) return(-1); - } bl->n = blockers; if(blockers) blockers->p = bl; blockers = bl; - if(to > 0) - addtimeout(bl, bl->to = (time(NULL) + to)); - rv = yield(); ++ if(bl->to > 0) ++ addtimeout(bl, bl->to); + return(0); + } + + static void remblock(struct blocker *bl) + { + if(bl->to > 0) + deltimeout(bl); if(bl->n) bl->n->p = bl->p; if(bl->p) @@@ -280,8 -260,17 +326,14 @@@ int ioloop(void } } now = time(NULL); - while((timeheap.d > 0) && (timeheap.b[0].to <= now)) - resume(timeheap.b[0].bl->th, 0); - for(bl = blockers; bl; bl = nbl) { - nbl = bl->n; - if((bl->to != 0) && (bl->to <= now)) { - if(bl->id < 0) { - resume(bl->th, 0); - } else { - bl->rev = 0; - resume(bl->th, bl->id); - } ++ while((timeheap.d > 0) && (timeheap.b[0].to <= now)) { ++ if(bl->id < 0) { ++ resume(timeheap.b[0].bl->th, 0); ++ } else { ++ bl->rev = 0; ++ resume(bl->th, bl->id); + } + } } for(bl = blockers; bl; bl = bl->n) remfd(bl);