From a1cf37eb0f92d89bb0d10abbc89bbac7a434a6df Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 16 Jun 2017 18:59:34 -0600 Subject: [PATCH] rktio: repairs --- racket/src/rktio/rktio_fd.c | 4 +-- racket/src/rktio/rktio_hash.c | 45 ++++++++++++++++++++++++------- racket/src/rktio/rktio_ltps.c | 2 ++ racket/src/rktio/rktio_poll_set.c | 11 +++++--- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/racket/src/rktio/rktio_fd.c b/racket/src/rktio/rktio_fd.c index 84670a4140..f53044a0d4 100644 --- a/racket/src/rktio/rktio_fd.c +++ b/racket/src/rktio/rktio_fd.c @@ -378,10 +378,10 @@ void rktio_reliably_close(intptr_t s) static rktio_ok_t do_close(rktio_t *rktio, rktio_fd_t *rfd, int set_error) { int ok; - + #ifdef RKTIO_SYSTEM_UNIX int cr; - + # ifdef RKTIO_USE_FCNTL_AND_FORK_FOR_FILE_LOCKS if (!(rfd->modes & RKTIO_OPEN_SOCKET)) rktio_release_lockf(rktio, rfd->fd); diff --git a/racket/src/rktio/rktio_hash.c b/racket/src/rktio/rktio_hash.c index 97864395b4..d41fe58353 100644 --- a/racket/src/rktio/rktio_hash.c +++ b/racket/src/rktio/rktio_hash.c @@ -33,6 +33,8 @@ void rktio_hash_free(rktio_hash_t *ht, int free_values) free(ht->buckets); } + + free(ht); } int rktio_hash_is_empty(rktio_hash_t *ht) @@ -63,9 +65,9 @@ static void do_rehash(rktio_hash_t *ht, intptr_t new_size) ht->buckets = calloc(new_size, sizeof(bucket_t)); ht->count = 0; - for (i = old_size; --i; ) { - if (ht->buckets[i].v) - rktio_hash_set(ht, ht->buckets[i].key, ht->buckets[i].v); + for (i = old_size; i--; ) { + if (old_buckets[i].v) + rktio_hash_set(ht, old_buckets[i].key, old_buckets[i].v); } free(old_buckets); @@ -77,6 +79,7 @@ void *rktio_hash_get(rktio_hash_t *ht, intptr_t key) if (ht->buckets) { intptr_t mask = (ht->size - 1); intptr_t hc = key & mask; + intptr_t init_hc = hc; intptr_t d = ((key >> 3) & mask) | 0x1; while (1) { @@ -86,6 +89,10 @@ void *rktio_hash_get(rktio_hash_t *ht, intptr_t key) || (ht->buckets[hc].key == -1)) { /* keep looking */ hc = (hc + d) & mask; + if (hc == init_hc) { + /* didn't find in a table that has only full and vacated slots */ + return NULL; + } } else return NULL; } @@ -98,6 +105,7 @@ void rktio_hash_remove(rktio_hash_t *ht, intptr_t key, int dont_rehash) if (ht->buckets) { intptr_t mask = (ht->size - 1); intptr_t hc = key & mask; + intptr_t init_hc = hc; intptr_t d = ((key >> 3) & mask) | 0x1; while (1) { @@ -109,10 +117,15 @@ void rktio_hash_remove(rktio_hash_t *ht, intptr_t key, int dont_rehash) if (4 * ht->count <= ht->size) do_rehash(ht, ht->size >> 1); } + return; } else if (ht->buckets[hc].v || (ht->buckets[hc].key == -1)) { /* keep looking */ hc = (hc + d) & mask; + if (hc == init_hc) { + /* didn't find in a table that has only full and vacated slots */ + return; + } } else break; } @@ -125,27 +138,39 @@ void rktio_hash_set(rktio_hash_t *ht, intptr_t key, void *v) ht->size = 16; ht->buckets = calloc(ht->size, sizeof(bucket_t)); } - + { intptr_t mask = (ht->size - 1); intptr_t hc = key & mask; + intptr_t init_hc = hc,use_hc = -1; intptr_t d = ((key >> 3) & mask) | 0x1; while (1) { if (ht->buckets[hc].v) { - if (ht->buckets[hc].key == -1) { - /* use bucket whose content ws previously removed */ - break; + if (ht->buckets[hc].key == key) { + ht->buckets[hc].v = v; + return; } else { + if (ht->buckets[hc].key == -1) { + /* use bucket whose content was previously removed, but only + if we don't find it later */ + if (use_hc < 0) use_hc = hc; + } /* keep looking for a spot */ hc = (hc + d) & mask; + if (hc == init_hc) { + /* didn't find in a table that has only full and vacated slots */ + break; + } } - } else + } else { + if (use_hc < 0) use_hc = hc; break; + } } - ht->buckets[hc].key = key; - ht->buckets[hc].v = v; + ht->buckets[use_hc].key = key; + ht->buckets[use_hc].v = v; ht->count++; if (2 * ht->count >= ht->size) diff --git a/racket/src/rktio/rktio_ltps.c b/racket/src/rktio/rktio_ltps.c index a315d1cab2..980e84e480 100644 --- a/racket/src/rktio/rktio_ltps.c +++ b/racket/src/rktio/rktio_ltps.c @@ -15,6 +15,8 @@ #ifdef HAVE_POLL_SYSCALL # include # include +#elif defined(RKTIO_SYSTEM_UNIX) +# include #endif #ifdef HAVE_EPOLL_SYSCALL # include diff --git a/racket/src/rktio/rktio_poll_set.c b/racket/src/rktio/rktio_poll_set.c index ca49178bd7..c5c7dbc49b 100644 --- a/racket/src/rktio/rktio_poll_set.c +++ b/racket/src/rktio/rktio_poll_set.c @@ -91,6 +91,7 @@ rktio_poll_set_t *rktio_get_fdset(rktio_poll_set_t *fdarray, int pos) void rktio_fdzero(rktio_poll_set_t *fd) { fd->data->count = 0; + fd->data->skip_sleep = 0; } static int find_fd_pos(struct rktio_fd_set_data_t *data, int n) @@ -192,6 +193,9 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) rktio_clean_fd_set(fds); rktio_clean_fd_set(src_fds); + if (src_data->skip_sleep) + data->skip_sleep = 1; + c = data->count; sc = src_data->count; @@ -322,7 +326,7 @@ static rktio_poll_set_t *alloc_fdset_arrays() /* Allocate an array with 1 extra intptr_t in each set to hold a "max" fd counter, and 1 extra intger used to record "no sleeping" */ - + p = malloc(3 * (dynamic_fd_size + sizeof(intptr_t) + sizeof(int))); return p; @@ -810,8 +814,9 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) i = FDSET_LIMIT(sp); FDSET_LIMIT(p) = i; } -# endif -# if defined(USE_DYNAMIC_FDSET_SIZE) + /* `i` is max fd, so add 1 to get count, then convert to bytes (rounding up) */ + i = (i + 1 + 7) >> 3; +# elif defined(USE_DYNAMIC_FDSET_SIZE) i = dynamic_fd_size; # else i = sizeof(fd_set);