Skip to content

Commit

Permalink
Maxfds stored in thread-local context
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
  • Loading branch information
sustrik committed Feb 24, 2017
1 parent ef9ed7d commit b4800b6
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 49 deletions.
16 changes: 1 addition & 15 deletions cr.c
Expand Up @@ -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) {
Expand All @@ -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. */
/******************************************************************************/
Expand Down
6 changes: 0 additions & 6 deletions cr.h
Expand Up @@ -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);
Expand Down
11 changes: 8 additions & 3 deletions epoll.c.inc
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions epoll.h.inc
Expand Up @@ -23,6 +23,8 @@
#ifndef DILL_EPOLL_INCLUDED
#define DILL_EPOLL_INCLUDED

#include <stdint.h>

#include "cr.h"
#include "list.h"

Expand All @@ -37,6 +39,7 @@ struct dill_fdclause {
struct dill_ctx_pollset {
int efd;
struct dill_fdinfo *fdinfos;
size_t nfdinfos;
uint32_t changelist;
};

Expand Down
8 changes: 2 additions & 6 deletions fd.c
Expand Up @@ -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;
}
Expand Down
11 changes: 8 additions & 3 deletions kqueue.c.inc
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion kqueue.h.inc
@@ -1,4 +1,3 @@
/* -*- mode: c; -*- */
/*
Copyright (c) 2016 Martin Sustrik
Expand Down Expand Up @@ -36,6 +35,7 @@ struct dill_fdclause {

struct dill_ctx_pollset {
int kfd;
int nfdinfos;
struct dill_fdinfo *fdinfos;
uint32_t changelist;
};
Expand Down
6 changes: 3 additions & 3 deletions libdill.c
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -76,6 +76,6 @@ int fdout(int fd, int64_t deadline) {
}

int fdclean(int fd) {
return dill_clean(fd);
return dill_pollset_clean(fd);
}

13 changes: 7 additions & 6 deletions poll.c.inc
Expand Up @@ -52,7 +52,7 @@
+------+------+------+----------------------------------------+--------+
ctx->fdinfos ^
|
dill_maxfds
ctx->nfdinfos
*/

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions poll.h.inc
Expand Up @@ -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;
};

Expand Down
16 changes: 10 additions & 6 deletions utils.h
Expand Up @@ -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
Expand Down

0 comments on commit b4800b6

Please sign in to comment.