From b4800b6de4f9571b859f344fd22bb534fc652777 Mon Sep 17 00:00:00 2001 From: Martin Sustrik Date: Fri, 24 Feb 2017 21:46:49 +0100 Subject: [PATCH] Maxfds stored in thread-local context Signed-off-by: Martin Sustrik --- cr.c | 16 +--------------- cr.h | 6 ------ epoll.c.inc | 11 ++++++++--- epoll.h.inc | 3 +++ fd.c | 8 ++------ kqueue.c.inc | 11 ++++++++--- kqueue.h.inc | 2 +- libdill.c | 6 +++--- poll.c.inc | 13 +++++++------ poll.h.inc | 1 + utils.h | 16 ++++++++++------ 11 files changed, 44 insertions(+), 49 deletions(-) diff --git a/cr.c b/cr.c index 2ed4e352..8035a437 100644 --- a/cr.c +++ b/cr.c @@ -114,7 +114,7 @@ void dill_ctx_cr_term(struct dill_ctx_cr *ctx) { } /******************************************************************************/ -/* Poller. */ +/* Timers. */ /******************************************************************************/ static void dill_timer_cancel(struct dill_clause *cl) { @@ -135,20 +135,6 @@ void dill_timer(struct dill_tmclause *tmcl, int id, int64_t deadline) { dill_waitfor(&tmcl->cl, id, dill_timer_cancel); } -int dill_in(struct dill_fdclause *fdcl, int id, int fd) { - if(dill_slow(fd < 0 || fd >= dill_maxfds())) {errno = EBADF; return -1;} - return dill_pollset_in(fdcl, id, fd); -} - -int dill_out(struct dill_fdclause *fdcl, int id, int fd) { - if(dill_slow(fd < 0 || fd >= dill_maxfds())) {errno = EBADF; return -1;} - return dill_pollset_out(fdcl, id, fd); -} - -int dill_clean(int fd) { - return dill_pollset_clean(fd); -} - /******************************************************************************/ /* Handle implementation. */ /******************************************************************************/ diff --git a/cr.h b/cr.h index daa67032..3fde9f1d 100644 --- a/cr.h +++ b/cr.h @@ -146,12 +146,6 @@ void dill_trigger(struct dill_clause *cl, int err); /* Add a timer to the list of active clauses. */ void dill_timer(struct dill_tmclause *tmcl, int id, int64_t deadline); -/* Wait for an in event on a file descriptor. */ -int dill_in(struct dill_fdclause *fdcl, int id, int fd); - -/* Wait for an out event on a file descriptor. */ -int dill_out(struct dill_fdclause *fdcl, int id, int fd); - /* Returns 0 if blocking functions are allowed. Returns -1 and sets errno to ECANCELED otherwise. */ int dill_canblock(void); diff --git a/epoll.c.inc b/epoll.c.inc index b2891c57..62a89537 100644 --- a/epoll.c.inc +++ b/epoll.c.inc @@ -57,7 +57,8 @@ struct dill_fdinfo { int dill_ctx_pollset_init(struct dill_ctx_pollset *ctx) { int err; /* Allocate one info per fd. */ - ctx->fdinfos = calloc(dill_maxfds(), sizeof(struct dill_fdinfo)); + ctx->nfdinfos = dill_maxfds(); + ctx->fdinfos = calloc(ctx->nfdinfos, sizeof(struct dill_fdinfo)); if(dill_slow(!ctx->fdinfos)) {err = ENOMEM; goto error1;} /* Changelist is empty. */ ctx->changelist = DILL_ENDLIST; @@ -103,8 +104,10 @@ static void dill_fdcancelout(struct dill_clause *cl) { int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; - /* If not yet cached, check whether the fd exists and if it does, add it to the pollset. */ + /* If not yet cached, check whether the fd exists and if it does, + add it to the pollset. */ if(dill_slow(!fdi->cached)) { struct epoll_event ev; ev.data.fd = fd; @@ -134,8 +137,10 @@ int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { int dill_pollset_out(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; - /* If not yet cached, check whether the fd exists and if it does, add it to pollset. */ + /* If not yet cached, check whether the fd exists and if it does, + add it to pollset. */ if(dill_slow(!fdi->cached)) { struct epoll_event ev; ev.data.fd = fd; diff --git a/epoll.h.inc b/epoll.h.inc index 16967b1e..892cc542 100644 --- a/epoll.h.inc +++ b/epoll.h.inc @@ -23,6 +23,8 @@ #ifndef DILL_EPOLL_INCLUDED #define DILL_EPOLL_INCLUDED +#include + #include "cr.h" #include "list.h" @@ -37,6 +39,7 @@ struct dill_fdclause { struct dill_ctx_pollset { int efd; struct dill_fdinfo *fdinfos; + size_t nfdinfos; uint32_t changelist; }; diff --git a/fd.c b/fd.c index db4983bc..87911e84 100644 --- a/fd.c +++ b/fd.c @@ -29,19 +29,15 @@ #include "utils.h" int dill_maxfds(void) { - /* Return a cached value if possible. */ - static int maxfds = -1; - if(dill_fast(maxfds >= 0)) return maxfds; /* Get the maximum number of file descriptors. */ struct rlimit rlim; int rc = getrlimit(RLIMIT_NOFILE, &rlim); dill_assert(rc == 0); - maxfds = rlim.rlim_max; + int maxfds = rlim.rlim_max; #if defined BSD /* On newer versions of OSX, the above behaves weirdly and returns -1, so use OPEN_MAX instead. */ - if(maxfds < 0) - maxfds = OPEN_MAX; + if(maxfds < 0) return OPEN_MAX; #endif return maxfds; } diff --git a/kqueue.c.inc b/kqueue.c.inc index a9f81412..7da8e349 100644 --- a/kqueue.c.inc +++ b/kqueue.c.inc @@ -61,7 +61,8 @@ struct dill_fdinfo { int dill_ctx_pollset_init(struct dill_ctx_pollset *ctx) { int err; /* Allocate one info per fd. */ - ctx->fdinfos = calloc(dill_maxfds(), sizeof(struct dill_fdinfo)); + ctx->nfdinfos = dill_maxfds(); + ctx->fdinfos = calloc(ctx->nfdinfos, sizeof(struct dill_fdinfo)); if(dill_slow(!ctx->fdinfos)) {err = ENOMEM; goto error1;} /* Changelist is empty. */ ctx->changelist = DILL_ENDLIST; @@ -110,8 +111,10 @@ static void dill_fdcancelout(struct dill_clause *cl) { int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; - /* If not yet cached, check whether fd exists and if so add it to pollset. */ + /* If not yet cached, check whether fd exists and if so add it + to pollset. */ if(dill_slow(!fdi->cached)) { struct kevent ev; EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0); @@ -139,8 +142,10 @@ int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { int dill_pollset_out(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; - /* If not yet cached, check whether the fd exists and if it does, add it to the pollset. */ + /* If not yet cached, check whether the fd exists and if it does, + add it to the pollset. */ if(dill_slow(!fdi->cached)) { struct kevent ev; EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); diff --git a/kqueue.h.inc b/kqueue.h.inc index bfb8ee92..869b0b27 100644 --- a/kqueue.h.inc +++ b/kqueue.h.inc @@ -1,4 +1,3 @@ -/* -*- mode: c; -*- */ /* Copyright (c) 2016 Martin Sustrik @@ -36,6 +35,7 @@ struct dill_fdclause { struct dill_ctx_pollset { int kfd; + int nfdinfos; struct dill_fdinfo *fdinfos; uint32_t changelist; }; diff --git a/libdill.c b/libdill.c index cb78b05a..a7cd3aea 100644 --- a/libdill.c +++ b/libdill.c @@ -45,7 +45,7 @@ int fdin(int fd, int64_t deadline) { if(dill_slow(rc < 0)) return -1; /* Start waiting for the fd. */ struct dill_fdclause fdcl; - rc = dill_in(&fdcl, 1, fd); + rc = dill_pollset_in(&fdcl, 1, fd); if(dill_slow(rc < 0)) return -1; /* Optionally, start waiting for a timer. */ struct dill_tmclause tmcl; @@ -63,7 +63,7 @@ int fdout(int fd, int64_t deadline) { if(dill_slow(rc < 0)) return -1; /* Start waiting for the fd. */ struct dill_fdclause fdcl; - rc = dill_out(&fdcl, 1, fd); + rc = dill_pollset_out(&fdcl, 1, fd); if(dill_slow(rc < 0)) return -1; /* Optionally, start waiting for a timer. */ struct dill_tmclause tmcl; @@ -76,6 +76,6 @@ int fdout(int fd, int64_t deadline) { } int fdclean(int fd) { - return dill_clean(fd); + return dill_pollset_clean(fd); } diff --git a/poll.c.inc b/poll.c.inc index 71694b96..cb78db85 100644 --- a/poll.c.inc +++ b/poll.c.inc @@ -52,7 +52,7 @@ +------+------+------+----------------------------------------+--------+ ctx->fdinfos ^ | - dill_maxfds + ctx->nfdinfos */ @@ -71,16 +71,17 @@ struct dill_fdinfo { int dill_ctx_pollset_init(struct dill_ctx_pollset *ctx) { int err; + ctx->nfdinfos = dill_maxfds(); /* Allocate largest possible pollset. */ ctx->pollset_size = 0; - ctx->pollset = malloc(sizeof(struct pollfd) * dill_maxfds()); + ctx->pollset = malloc(sizeof(struct pollfd) * ctx->nfdinfos); if(dill_slow(!ctx->pollset)) {err = ENOMEM; goto error1;} - ctx->fdinfos = malloc(sizeof(struct dill_fdinfo) * dill_maxfds()); + ctx->fdinfos = malloc(sizeof(struct dill_fdinfo) * ctx->nfdinfos); if(dill_slow(!ctx->fdinfos)) {err = ENOMEM; goto error2;} /* Intialise fd infos. There's no fd in the pollset, so set all indices to -1. */ int i; - for(i = 0; i != dill_maxfds(); ++i) { + for(i = 0; i != ctx->nfdinfos; ++i) { ctx->fdinfos[i].idx = -1; ctx->fdinfos[i].in = NULL; ctx->fdinfos[i].out = NULL; @@ -120,6 +121,7 @@ static void dill_fdcancelout(struct dill_clause *cl) { int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; if(dill_slow(!fdi->cached)) { int flags = fcntl(fd, F_GETFD); @@ -128,7 +130,6 @@ int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { fdi->cached = 1; } if(fdi->idx < 0) { - dill_assert(ctx->pollset_size < dill_maxfds()); fdi->idx = ctx->pollset_size; ++ctx->pollset_size; ctx->pollset[fdi->idx].fd = fd; @@ -143,6 +144,7 @@ int dill_pollset_in(struct dill_fdclause *fdcl, int id, int fd) { int dill_pollset_out(struct dill_fdclause *fdcl, int id, int fd) { struct dill_ctx_pollset *ctx = &dill_getctx->pollset; + if(dill_slow(fd < 0 || fd >= ctx->nfdinfos)) {errno = EBADF; return -1;} struct dill_fdinfo *fdi = &ctx->fdinfos[fd]; if(dill_slow(!fdi->cached)) { int flags = fcntl(fd, F_GETFD); @@ -151,7 +153,6 @@ int dill_pollset_out(struct dill_fdclause *fdcl, int id, int fd) { fdi->cached = 1; } if(fdi->idx < 0) { - dill_assert(ctx->pollset_size < dill_maxfds()); fdi->idx = ctx->pollset_size; ++ctx->pollset_size; ctx->pollset[fdi->idx].fd = fd; diff --git a/poll.h.inc b/poll.h.inc index b6e9e284..5a26b70e 100644 --- a/poll.h.inc +++ b/poll.h.inc @@ -41,6 +41,7 @@ struct dill_ctx_pollset { struct pollfd *pollset; /* Info about all file descriptors. File descriptors are used as indices in this array. */ + int nfdinfos; struct dill_fdinfo *fdinfos; }; diff --git a/utils.h b/utils.h index 78edd244..6a00de60 100644 --- a/utils.h +++ b/utils.h @@ -65,18 +65,22 @@ }\ } while (0) - /* Workaround missing __rdtsc in Clang < 3.5 (or Clang < 6.0 on Xcode) */ #if defined(__x86_64__) || defined(__i386__) #if defined __clang__ -#if (!defined(__apple_build_version__) &&\ - ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 5))))\ - || (defined(__apple_build_version__) && (__clang_major__ < 6)) +#if (!defined(__apple_build_version__) && \ + ((__clang_major__ < 3) || \ + ((__clang_major__ == 3) && (__clang_minor__ < 5)))) || \ + (defined(__apple_build_version__) && (__clang_major__ < 6)) static inline uint64_t __rdtsc() { #if defined __i386__ - uint64_t x; asm volatile ("rdtsc" : "=A" (x)); return x; + uint64_t x; + asm volatile ("rdtsc" : "=A" (x)); + return x; #else - uint64_t a, d; asm volatile ("rdtsc" : "=a" (a), "=d" (d)); return (d<<32) | a; + uint64_t a, d; + asm volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d << 32) | a; #endif } #endif