Loading Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ makedirs: all: default test system_tests test_internals run examples clean: makedirs update_git_submodules rm -rf ./bin/*.a ./bin/*.so rm -rf ./bin/**/* rm -f $(OUT_DIR)/*.o $(OUT_DIR)/*.a *.core *.log bundle exec rake clobber Loading src/lib/bus/bus_example.c +1 −1 Original line number Diff line number Diff line Loading @@ -369,8 +369,8 @@ static void completion_cb(bus_msg_result_t *res, void *udata) { case BUS_SEND_SUCCESS: { #if INCREMENT_COMPLETION_COUNTER size_t cur = s->completed_deliveries; for (;;) { size_t cur = s->completed_deliveries; if (ATOMIC_BOOL_COMPARE_AND_SWAP(&s->completed_deliveries, cur, cur + 1)) { LOG(3, " -- ! got %zd bytes, seq_id 0x%08llx, %p\n", si->cur_payload_size, res->u.response.seq_id, Loading src/lib/bus/test_yacht.c +17 −4 Original line number Diff line number Diff line Loading @@ -48,9 +48,14 @@ TEST yacht_should_add_and_remove_accurately(uint8_t sz2) { ASSERT(y); for (int i = 0; i < (1 << (sz2 - 1)); i++) { ASSERT(yacht_set(y, i, NULL, NULL)); uintptr_t v = 1; void *old = NULL; ASSERT(yacht_set(y, i, (void *)v, &old)); ASSERT_EQ(NULL, old); ASSERT(yacht_member(y, i)); ASSERT(yacht_remove(y, i, NULL)); void *old2 = NULL; ASSERT(yacht_remove(y, i, &old2)); ASSERT_EQ((void *)1, old2); ASSERT(!yacht_member(y, i)); /* Add it back, to ensure it isn't disturbed by other removes */ ASSERT(yacht_set(y, i, NULL, NULL)); Loading Loading @@ -126,9 +131,17 @@ TEST yacht_should_grow_and_add_and_remove_accurately_out_of_order(uint8_t sz2) { for (int i = 0; i < (1 << (sz2 - 1)); i++) { int iv = i * other_large_prime; ASSERT(yacht_set(y, iv, NULL, NULL)); uintptr_t v = 1; void *old = NULL; ASSERT(yacht_set(y, iv, (void *)v, &old)); ASSERT_EQ(NULL, old); ASSERT(yacht_member(y, iv)); ASSERT(yacht_remove(y, iv, NULL)); void *old2 = NULL; ASSERT(yacht_remove(y, iv, &old2)); ASSERT_EQ((void*)v, old2); ASSERT(!yacht_member(y, iv)); /* Add it back, to ensure it isn't disturbed by other removes */ ASSERT(yacht_set(y, iv, NULL, NULL)); Loading src/lib/bus/yacht.c +21 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #define LOG(...) #endif #define USE_BRENTS_VARIATION 0 /* Yet Another C Hash Table: * An (int set) hash table for tracking active file descriptors * and their metadata. */ Loading Loading @@ -78,7 +80,7 @@ static size_t hash(int key) { bool yacht_get(struct yacht *y, int key, void **value) { size_t b = hash(key) & y->mask; LOG(" -- getting %d with bucket %d\n", key, b); LOG(" -- getting key %d with bucket %zd\n", key, b); for (size_t o = 0; o < y->size; o++) { size_t i = (b + o) & y->mask; // wrap as necessary Loading @@ -101,7 +103,7 @@ bool yacht_member(struct yacht *y, int key) { /* Set KEY to VALUE in the table. */ bool yacht_set(struct yacht *y, int key, void *value, void **old_value) { LOG(" -- adding %d with bucket %d\n", key, b); LOG(" -- setting key %d\n", key); for (;;) { size_t max = y->size / 2; Loading @@ -123,7 +125,7 @@ static bool insert(int *buckets, void **values, if (o > 0) { LOG(" -- o %zd (max_fill %zd)\n", o, max_fill); } size_t i = (b + o) & mask; // wrap as necessary int bv = buckets[i]; LOG(" -- b %d: %d\n", i, bv); LOG(" -- b %zd: %d\n", i, bv); if (bv == key) { if (old_value) { *old_value = values[i]; } values[i] = value; Loading @@ -133,18 +135,26 @@ static bool insert(int *buckets, void **values, values[i] = value; return true; } else { #if USE_BRENTS_VARIATION /* FIXME: This is not speeding things up significantly, and * during a grow the key / value being refiled need to * be updated in yacht_set or this will drop values. * Disable it for now. */ /* Brent's variation -- bump out key if not in its main spot */ size_t ob = hash(bv) & mask; /* other's primary bucket */ if (ob == i) { /* keep looking for an open spot */ continue; } else { /* refile it instead */ int okey = buckets[i]; LOG(" -- SWAPPING KEYS, %d => %d\n", key, bv); buckets[i] = key; key = okey; void *oval = values[i]; values[i] = value; value = oval; } #endif } } return false; /* too full */ Loading @@ -156,8 +166,11 @@ static bool grow(struct yacht *y) { size_t nmask = nsize - 1; int *nbuckets = NULL; void **nvalues = NULL; nbuckets = calloc(nsize, sizeof(*nbuckets)); nbuckets = malloc(nsize * sizeof(*nbuckets)); if (nbuckets == NULL) { return false; } for (int i = 0; i < nsize; i++) { nbuckets[i] = YACHT_NO_KEY; } nvalues = calloc(nsize, sizeof(*nvalues)); if (nvalues == NULL) { free(nbuckets); Loading @@ -167,7 +180,7 @@ static bool grow(struct yacht *y) { for (size_t i = 0; i < y->size; i++) { int key = y->buckets[i]; if (key != YACHT_NO_KEY && key != YACHT_DELETED) { if (!insert(nbuckets, nvalues, nmask, y->size, key, y->values[i], NULL)) { if (!insert(nbuckets, nvalues, nmask, nsize, key, y->values[i], NULL)) { goto cleanup; } } Loading @@ -182,18 +195,19 @@ static bool grow(struct yacht *y) { cleanup: if (nbuckets) { free(nbuckets); } if (nvalues) { free(nvalues); } return false; } /* Remove KEY from the table. */ bool yacht_remove(struct yacht *y, int key, void **old_value) { size_t b = hash(key) & y->mask; LOG(" -- removing %d with bucket %d\n", key, b); LOG(" -- removing %d with bucket %zd\n", key, b); for (size_t o = 0; o < y->size; o++) { size_t i = (b + o) & y->mask; // wrap as necessary int bv = y->buckets[i]; LOG(" -- b %d: %d\n", i, bv); LOG(" -- b %zd: %d\n", i, bv); if (bv == key) { if (y->buckets[(i + 1) & y->mask] == YACHT_NO_KEY) { y->buckets[i] = YACHT_NO_KEY; Loading Loading
Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ makedirs: all: default test system_tests test_internals run examples clean: makedirs update_git_submodules rm -rf ./bin/*.a ./bin/*.so rm -rf ./bin/**/* rm -f $(OUT_DIR)/*.o $(OUT_DIR)/*.a *.core *.log bundle exec rake clobber Loading
src/lib/bus/bus_example.c +1 −1 Original line number Diff line number Diff line Loading @@ -369,8 +369,8 @@ static void completion_cb(bus_msg_result_t *res, void *udata) { case BUS_SEND_SUCCESS: { #if INCREMENT_COMPLETION_COUNTER size_t cur = s->completed_deliveries; for (;;) { size_t cur = s->completed_deliveries; if (ATOMIC_BOOL_COMPARE_AND_SWAP(&s->completed_deliveries, cur, cur + 1)) { LOG(3, " -- ! got %zd bytes, seq_id 0x%08llx, %p\n", si->cur_payload_size, res->u.response.seq_id, Loading
src/lib/bus/test_yacht.c +17 −4 Original line number Diff line number Diff line Loading @@ -48,9 +48,14 @@ TEST yacht_should_add_and_remove_accurately(uint8_t sz2) { ASSERT(y); for (int i = 0; i < (1 << (sz2 - 1)); i++) { ASSERT(yacht_set(y, i, NULL, NULL)); uintptr_t v = 1; void *old = NULL; ASSERT(yacht_set(y, i, (void *)v, &old)); ASSERT_EQ(NULL, old); ASSERT(yacht_member(y, i)); ASSERT(yacht_remove(y, i, NULL)); void *old2 = NULL; ASSERT(yacht_remove(y, i, &old2)); ASSERT_EQ((void *)1, old2); ASSERT(!yacht_member(y, i)); /* Add it back, to ensure it isn't disturbed by other removes */ ASSERT(yacht_set(y, i, NULL, NULL)); Loading Loading @@ -126,9 +131,17 @@ TEST yacht_should_grow_and_add_and_remove_accurately_out_of_order(uint8_t sz2) { for (int i = 0; i < (1 << (sz2 - 1)); i++) { int iv = i * other_large_prime; ASSERT(yacht_set(y, iv, NULL, NULL)); uintptr_t v = 1; void *old = NULL; ASSERT(yacht_set(y, iv, (void *)v, &old)); ASSERT_EQ(NULL, old); ASSERT(yacht_member(y, iv)); ASSERT(yacht_remove(y, iv, NULL)); void *old2 = NULL; ASSERT(yacht_remove(y, iv, &old2)); ASSERT_EQ((void*)v, old2); ASSERT(!yacht_member(y, iv)); /* Add it back, to ensure it isn't disturbed by other removes */ ASSERT(yacht_set(y, iv, NULL, NULL)); Loading
src/lib/bus/yacht.c +21 −7 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #define LOG(...) #endif #define USE_BRENTS_VARIATION 0 /* Yet Another C Hash Table: * An (int set) hash table for tracking active file descriptors * and their metadata. */ Loading Loading @@ -78,7 +80,7 @@ static size_t hash(int key) { bool yacht_get(struct yacht *y, int key, void **value) { size_t b = hash(key) & y->mask; LOG(" -- getting %d with bucket %d\n", key, b); LOG(" -- getting key %d with bucket %zd\n", key, b); for (size_t o = 0; o < y->size; o++) { size_t i = (b + o) & y->mask; // wrap as necessary Loading @@ -101,7 +103,7 @@ bool yacht_member(struct yacht *y, int key) { /* Set KEY to VALUE in the table. */ bool yacht_set(struct yacht *y, int key, void *value, void **old_value) { LOG(" -- adding %d with bucket %d\n", key, b); LOG(" -- setting key %d\n", key); for (;;) { size_t max = y->size / 2; Loading @@ -123,7 +125,7 @@ static bool insert(int *buckets, void **values, if (o > 0) { LOG(" -- o %zd (max_fill %zd)\n", o, max_fill); } size_t i = (b + o) & mask; // wrap as necessary int bv = buckets[i]; LOG(" -- b %d: %d\n", i, bv); LOG(" -- b %zd: %d\n", i, bv); if (bv == key) { if (old_value) { *old_value = values[i]; } values[i] = value; Loading @@ -133,18 +135,26 @@ static bool insert(int *buckets, void **values, values[i] = value; return true; } else { #if USE_BRENTS_VARIATION /* FIXME: This is not speeding things up significantly, and * during a grow the key / value being refiled need to * be updated in yacht_set or this will drop values. * Disable it for now. */ /* Brent's variation -- bump out key if not in its main spot */ size_t ob = hash(bv) & mask; /* other's primary bucket */ if (ob == i) { /* keep looking for an open spot */ continue; } else { /* refile it instead */ int okey = buckets[i]; LOG(" -- SWAPPING KEYS, %d => %d\n", key, bv); buckets[i] = key; key = okey; void *oval = values[i]; values[i] = value; value = oval; } #endif } } return false; /* too full */ Loading @@ -156,8 +166,11 @@ static bool grow(struct yacht *y) { size_t nmask = nsize - 1; int *nbuckets = NULL; void **nvalues = NULL; nbuckets = calloc(nsize, sizeof(*nbuckets)); nbuckets = malloc(nsize * sizeof(*nbuckets)); if (nbuckets == NULL) { return false; } for (int i = 0; i < nsize; i++) { nbuckets[i] = YACHT_NO_KEY; } nvalues = calloc(nsize, sizeof(*nvalues)); if (nvalues == NULL) { free(nbuckets); Loading @@ -167,7 +180,7 @@ static bool grow(struct yacht *y) { for (size_t i = 0; i < y->size; i++) { int key = y->buckets[i]; if (key != YACHT_NO_KEY && key != YACHT_DELETED) { if (!insert(nbuckets, nvalues, nmask, y->size, key, y->values[i], NULL)) { if (!insert(nbuckets, nvalues, nmask, nsize, key, y->values[i], NULL)) { goto cleanup; } } Loading @@ -182,18 +195,19 @@ static bool grow(struct yacht *y) { cleanup: if (nbuckets) { free(nbuckets); } if (nvalues) { free(nvalues); } return false; } /* Remove KEY from the table. */ bool yacht_remove(struct yacht *y, int key, void **old_value) { size_t b = hash(key) & y->mask; LOG(" -- removing %d with bucket %d\n", key, b); LOG(" -- removing %d with bucket %zd\n", key, b); for (size_t o = 0; o < y->size; o++) { size_t i = (b + o) & y->mask; // wrap as necessary int bv = y->buckets[i]; LOG(" -- b %d: %d\n", i, bv); LOG(" -- b %zd: %d\n", i, bv); if (bv == key) { if (y->buckets[(i + 1) & y->mask] == YACHT_NO_KEY) { y->buckets[i] = YACHT_NO_KEY; Loading