dns_qpkey_t ascii;
} item[256 * 256 / 4];
-static uint32_t
+static void
fuzz_attach(void *ctx, void *pval, uint32_t ival) {
assert(ctx == NULL);
assert(pval == &item[ival]);
- return (item[ival].refcount++);
+ item[ival].refcount++;
}
-static uint32_t
+static void
fuzz_detach(void *ctx, void *pval, uint32_t ival) {
assert(ctx == NULL);
assert(pval == &item[ival]);
- assert(item[ival].refcount > 0);
- return (item[ival].refcount--);
+ item[ival].refcount--;
}
static size_t
strlcpy(buf, "fuzz", size);
}
-const struct dns_qpmethods fuzz_methods = {
+const dns_qpmethods_t fuzz_methods = {
fuzz_attach,
fuzz_detach,
fuzz_makekey,
* Read-only parts of a qp-trie.
*
* A `dns_qpreader_t` is the common prefix of the `dns_qpreadable`
- * types, containing just the fields neded for the hot path.
+ * types, containing just the fields neded for the hot path. The
+ * internals of a `dns_qpreader_t` are private; they are only exposed
+ * so that callers can allocate a `dns_qpread_t` on the stack.
*
* Ranty aside: annoyingly, C doesn't allow us to use a predeclared
* structure type as an anonymous struct member, so we have to use a
* The caller provides space for it on the stack; it can be
* used by only one thread. As well as the `DNS_QPREADER_FIELDS`,
* it contains a thread ID to check for incorrect usage.
+ *
+ * The internals of a `dns_qpread_t` are private; they are only
+ * exposed so that callers can allocate an instance on the stack.
*/
typedef struct dns_qpread {
DNS_QPREADER_FIELDS;
* The `attach` and `detach` methods adjust reference counts on value
* objects. They support copy-on-write and safe memory reclamation
* needed for multi-version concurrency. The methods are only called
- * when the `dns_qpmulti_t` mutex is held. For tracing purposes, they
- * should return the same value as `isc_refcount_increment()` or
- * `isc_refcount_decrement()`, respectively
+ * when the `dns_qpmulti_t` mutex is held.
*
* Note: When a value object reference count is greater than one, the
* object is in use by concurrent readers so it must not be modified. A
* readable identifier into `buf` which has max length `size`.
*/
typedef struct dns_qpmethods {
- uint32_t (*attach)(void *uctx, void *pval, uint32_t ival);
- uint32_t (*detach)(void *uctx, void *pval, uint32_t ival);
+ void (*attach)(void *uctx, void *pval, uint32_t ival);
+ void (*detach)(void *uctx, void *pval, uint32_t ival);
size_t (*makekey)(dns_qpkey_t key, void *uctx, void *pval,
uint32_t ival);
void (*triename)(void *uctx, char *buf, size_t size);
alloc_twigs(dns_qp_t *qp, qp_weight_t size) {
qp_chunk_t chunk = qp->bump;
qp_cell_t cell = qp->usage[chunk].used;
+
if (cell + size <= QP_CHUNK_SIZE) {
qp->usage[chunk].used += size;
qp->used_count += size;
qp_weight_t size = branch_twigs_size(parent);
qp_ref_t twigs_ref = branch_twigs_ref(parent);
qp_chunk_t chunk = ref_chunk(twigs_ref);
+
if (qp->compact_all ||
(chunk != qp->bump && chunk_usage(qp, chunk) < QP_MIN_USED))
{
static dns_qp_t *
transaction_open(dns_qpmulti_t *multi, dns_qp_t **qptp) {
- dns_qp_t *qp;
-
REQUIRE(QPMULTI_VALID(multi));
REQUIRE(qptp != NULL && *qptp == NULL);
LOCK(&multi->mutex);
- qp = &multi->writer;
-
+ dns_qp_t *qp = &multi->writer;
INSIST(QP_VALID(qp));
/*
void
dns_qp_create(isc_mem_t *mctx, const dns_qpmethods_t *methods, void *uctx,
dns_qp_t **qptp) {
- dns_qp_t *qp;
-
REQUIRE(qptp != NULL && *qptp == NULL);
- qp = isc_mem_get(mctx, sizeof(*qp));
+ dns_qp_t *qp = isc_mem_get(mctx, sizeof(*qp));
QP_INIT(qp, methods, uctx);
isc_mem_attach(mctx, &qp->mctx);
alloc_reset(qp);
dns_qpmulti_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
const dns_qpmethods_t *methods, void *uctx,
dns_qpmulti_t **qpmp) {
- dns_qpmulti_t *multi;
- dns_qp_t *qp;
-
REQUIRE(qpmp != NULL && *qpmp == NULL);
- multi = isc_mem_get(mctx, sizeof(*multi));
+ dns_qpmulti_t *multi = isc_mem_get(mctx, sizeof(*multi));
*multi = (dns_qpmulti_t){
.magic = QPMULTI_MAGIC,
.reader_ref = INVALID_REF,
* allocates; to ensure dns_qpmulti_write() does too, pretend the
* previous transaction was an update
*/
- qp = &multi->writer;
+ dns_qp_t *qp = &multi->writer;
QP_INIT(qp, methods, uctx);
isc_mem_attach(mctx, &qp->mctx);
qp->transaction_mode = QP_UPDATE;
void
dns_qp_destroy(dns_qp_t **qptp) {
- dns_qp_t *qp;
-
REQUIRE(qptp != NULL);
REQUIRE(QP_VALID(*qptp));
- qp = *qptp;
+ dns_qp_t *qp = *qptp;
*qptp = NULL;
/* do not try to destroy part of a dns_qpmulti_t */
void
dns_qpmulti_destroy(dns_qpmulti_t **qpmp) {
- dns_qp_t *qp = NULL;
- dns_qpmulti_t *multi = NULL;
-
REQUIRE(qpmp != NULL);
REQUIRE(QPMULTI_VALID(*qpmp));
- multi = *qpmp;
- qp = &multi->writer;
+ dns_qpmulti_t *multi = *qpmp;
+ dns_qp_t *qp = &multi->writer;
*qpmp = NULL;
REQUIRE(QP_VALID(qp));
dns_qp_insert(dns_qp_t *qp, void *pval, uint32_t ival) {
qp_ref_t new_ref, old_ref;
qp_node_t new_leaf, old_node;
- qp_node_t *new_twigs, *old_twigs;
+ qp_node_t *new_twigs = NULL, *old_twigs = NULL;
qp_shift_t new_bit, old_bit;
qp_weight_t old_size, new_size;
dns_qpkey_t new_key, old_key;
uint64_t index;
qp_shift_t bit;
qp_weight_t pos;
- qp_node_t *n;
+ qp_node_t *n = NULL;
REQUIRE(QP_VALID(qp));
isc_result_t
dns_qp_deletekey(dns_qp_t *qp, const dns_qpkey_t search_key,
size_t search_keylen) {
- dns_qpkey_t found_key;
- size_t found_keylen;
- qp_shift_t bit = 0; /* suppress warning */
- qp_weight_t pos, size;
- qp_ref_t ref;
- qp_node_t *twigs;
- qp_node_t *parent;
- qp_node_t *n;
-
REQUIRE(QP_VALID(qp));
REQUIRE(search_keylen < sizeof(dns_qpkey_t));
return (ISC_R_NOTFOUND);
}
- parent = NULL;
- n = make_root_mutable(qp);
+ qp_shift_t bit = 0; /* suppress warning */
+ qp_node_t *parent = NULL;
+ qp_node_t *n = make_root_mutable(qp);
while (is_branch(n)) {
prefetch_twigs(qp, n);
bit = branch_keybit(n, search_key, search_keylen);
n = branch_twig_ptr(qp, n, bit);
}
- found_keylen = leaf_qpkey(qp, n, found_key);
+ dns_qpkey_t found_key;
+ size_t found_keylen = leaf_qpkey(qp, n, found_key);
if (qpkey_compare(search_key, search_keylen, found_key, found_keylen) !=
QPKEY_EQUAL)
{
parent = NULL;
INSIST(bit != 0);
- size = branch_twigs_size(n);
- pos = branch_twig_pos(n, bit);
- ref = branch_twigs_ref(n);
- twigs = ref_ptr(qp, ref);
+ qp_weight_t size = branch_twigs_size(n);
+ qp_weight_t pos = branch_twig_pos(n, bit);
+ qp_ref_t ref = branch_twigs_ref(n);
+ qp_node_t *twigs = ref_ptr(qp, ref);
if (size == 2) {
/*
dns_qpkey_t found_key;
size_t found_keylen;
qp_shift_t bit;
- qp_node_t *n;
+ qp_node_t *n = NULL;
REQUIRE(QP_VALID(qp));
REQUIRE(pval_r != NULL);
size_t searchlen, foundlen;
size_t offset;
qp_shift_t bit;
- qp_node_t *n, *twigs;
+ qp_node_t *n = NULL, *twigs = NULL;
isc_result_t result;
unsigned int labels = 0;
struct offref {
* method invocation helpers
*/
-#if 0
-
-#define attach_leaf(qp, n) \
- do { \
- uint32_t iv = leaf_ival(n); \
- void *pv = leaf_pval(n); \
- uint32_t r = qp->methods->attach(qp->uctx, pv, iv); \
- fprintf(stderr, \
- "%s:%u:%s():t%u qp %p node %p leaf %p %u " \
- "(%u -> %u)\n", \
- __FILE__, __LINE__, __func__, isc_tid(), qp, n, pv, \
- iv, r, r + 1); \
- } while (0)
-
-#define detach_leaf(qp, n) \
- do { \
- uint32_t iv = leaf_ival(n); \
- void *pv = leaf_pval(n); \
- uint32_t r = qp->methods->detach(qp->uctx, pv, iv); \
- fprintf(stderr, \
- "%s:%u:%s():t%u qp %p node %p leaf %p %u " \
- "(%u -> %u)\n", \
- __FILE__, __LINE__, __func__, isc_tid(), qp, n, pv, \
- iv, r, r - 1); \
- } while (0)
-
-#else
-
static inline void
attach_leaf(dns_qpreadable_t qpr, qp_node_t *n) {
dns_qpreader_t *qp = dns_qpreader(qpr);
qp->methods->detach(qp->uctx, leaf_pval(n), leaf_ival(n));
}
-#endif
-
static inline size_t
leaf_qpkey(dns_qpreadable_t qpr, qp_node_t *n, dns_qpkey_t key) {
dns_qpreader_t *qp = dns_qpreader(qpr);
dns_fixedname_t fixed;
} item[1024 * 1024];
-static uint32_t
+static void
item_check(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
assert(pval == &item[ival]);
- return (1);
}
static size_t
strlcpy(buf, "test", size);
}
-const struct dns_qpmethods qpmethods = {
+const dns_qpmethods_t qpmethods = {
item_check,
item_check,
item_makekey,
#define FILE_CHECK(check, msg) \
do { \
if (!(check)) { \
- fprintf(stderr, "%s:%zu: %s\n", filename, count, msg); \
+ fprintf(stderr, "%s:%zu: %s\n", filename, lines, msg); \
exit(1); \
} \
} while (0)
int
main(int argc, char *argv[]) {
isc_result_t result;
+ const char *filename = NULL;
+ char *filetext = NULL;
+ off_t fileoff;
+ FILE *fp = NULL;
+ size_t filesize, lines = 0, wirebytes = 0, labels = 0;
+ char *pos = NULL, *file_end = NULL;
isc_mem_create(&mctx);
exit(1);
}
- const char *filename = argv[1];
- off_t fileoff;
+ filename = argv[1];
result = isc_file_getsize(filename, &fileoff);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "stat(%s): %s\n", filename,
isc_result_totext(result));
exit(1);
}
- size_t filesize = (size_t)fileoff;
+ filesize = (size_t)fileoff;
- char *filetext = isc_mem_get(mctx, filesize + 1);
- FILE *fp = fopen(filename, "r");
+ filetext = isc_mem_get(mctx, filesize + 1);
+ fp = fopen(filename, "r");
if (fp == NULL || fread(filetext, 1, filesize, fp) < filesize) {
fprintf(stderr, "read(%s): %s\n", filename, strerror(errno));
exit(1);
fclose(fp);
filetext[filesize] = '\0';
- size_t count = 0;
- size_t wirebytes = 0;
- size_t labels = 0;
-
- char *pos = filetext;
- char *file_end = pos + filesize;
+ pos = filetext;
+ file_end = pos + filesize;
while (pos < file_end) {
- FILE_CHECK(count < ARRAY_SIZE(item), "too many lines");
+ char *domain = NULL, *newline = NULL;
+ size_t len;
+
+ FILE_CHECK(lines < ARRAY_SIZE(item), "too many lines");
pos += strspn(pos, "0123456789");
FILE_CHECK(*pos++ == ',', "missing comma");
- char *domain = pos;
+ domain = pos;
pos += strcspn(pos, "\r\n");
FILE_CHECK(*pos != '\0', "missing newline");
- char *newline = pos;
+ newline = pos;
pos += strspn(pos, "\r\n");
- size_t len = newline - domain;
+ len = newline - domain;
- item[count].text = domain;
+ item[lines].text = domain;
domain[len] = '\0';
- dns_name_t *name = dns_fixedname_initname(&item[count].fixed);
+ dns_name_t *name = dns_fixedname_initname(&item[lines].fixed);
isc_buffer_t buffer;
isc_buffer_init(&buffer, domain, len);
isc_buffer_add(&buffer, len);
wirebytes += name->length;
labels += name->labels;
- count++;
+ lines++;
}
printf("names %g MB labels %g MB\n", (double)wirebytes / 1048576.0,
(double)labels / 1048576.0);
- size_t lines = count;
-
for (struct fun *fun = fun_list; fun->name != NULL; fun++) {
- isc_time_t t0;
- t0 = isc_time_now_hires();
-
isc_mem_t *mem = NULL;
+ void *map = NULL;
+
isc_mem_create(&mem);
- void *map = fun->new (mem);
+ map = fun->new (mem);
- for (count = 0; count < lines; count++) {
- result = fun->add(map, count);
+ isc_time_t t0 = isc_time_now_hires();
+ for (size_t n = 0; n < lines; n++) {
+ result = fun->add(map, n);
CHECK(result);
}
fun->sqz(map);
- isc_time_t t1;
- t1 = isc_time_now_hires();
-
- for (count = 0; count < lines; count++) {
+ isc_time_t t1 = isc_time_now_hires();
+ for (size_t n = 0; n < lines; n++) {
void *pval = NULL;
- result = fun->get(map, count, &pval);
+ result = fun->get(map, n, &pval);
CHECK(result);
- assert(pval == &item[count]);
+ assert(pval == &item[n]);
}
- isc_time_t t2;
- t2 = isc_time_now_hires();
-
+ isc_time_t t2 = isc_time_now_hires();
printf("%f sec to load %s\n",
(double)isc_time_microdiff(&t1, &t0) / (1000.0 * 1000.0),
fun->name);
return (dns_qpkey_fromname(key, &name));
}
-static uint32_t
+static void
smallname_attach(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
- return (isc_refcount_increment0(smallname_refcount(pval, ival)));
+ isc_refcount_increment0(smallname_refcount(pval, ival));
}
-static uint32_t
+static void
smallname_detach(void *ctx, void *pval, uint32_t ival) {
- uint32_t refs = isc_refcount_decrement(smallname_refcount(pval, ival));
- if (refs == 1) {
+ if (isc_refcount_decrement(smallname_refcount(pval, ival)) == 1) {
isc_mem_free(ctx, pval);
}
- return (refs);
}
static void
strlcpy(buf, "test", size);
}
-const struct dns_qpmethods methods = {
+const dns_qpmethods_t methods = {
smallname_attach,
smallname_detach,
qpkey_from_smallname,
static void
usage(void) {
fprintf(stderr,
- "usage: qp_dump [-drt] <filename>\n"
+ "usage: qp_dump [-dt] <filename>\n"
" -d output in graphviz dot format\n"
" -t output in ad-hoc indented text format\n");
}
int
main(int argc, char *argv[]) {
- bool dumpdot = false;
- bool dumptxt = false;
+ isc_result_t result;
+ dns_qp_t *qp = NULL;
+ const char *filename = NULL;
+ char *filetext = NULL;
+ size_t filesize;
+ off_t fileoff;
+ FILE *fp = NULL;
+ size_t wirebytes = 0, labels = 0, names = 0;
+ char *pos = NULL, *file_end = NULL;
+ bool dumpdot = false, dumptxt = false;
int opt;
while ((opt = isc_commandline_parse(argc, argv, "dt")) != -1) {
isc_mem_create(&mctx);
- const char *filename = argv[0];
- off_t fileoff;
- isc_result_t result = isc_file_getsize(filename, &fileoff);
+ filename = argv[0];
+ result = isc_file_getsize(filename, &fileoff);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "stat(%s): %s\n", filename,
isc_result_totext(result));
exit(1);
}
- size_t filesize = (size_t)fileoff;
- char *filetext = isc_mem_get(mctx, filesize + 1);
- FILE *fp = fopen(filename, "r");
+ filesize = (size_t)fileoff;
+ filetext = isc_mem_get(mctx, filesize + 1);
+ fp = fopen(filename, "r");
if (fp == NULL || fread(filetext, 1, filesize, fp) < filesize) {
fprintf(stderr, "read(%s): %s\n", filename, strerror(errno));
exit(1);
fclose(fp);
filetext[filesize] = '\0';
- dns_qp_t *qp = NULL;
dns_qp_create(mctx, &methods, NULL, &qp);
- size_t wirebytes = 0;
- size_t labels = 0;
- size_t names = 0;
- char *pos = filetext;
- char *file_end = pos + filesize;
+ pos = filetext;
+ file_end = pos + filesize;
while (pos < file_end) {
- char *domain = pos;
+ void *pval = NULL;
+ uint32_t ival = 0;
+ dns_fixedname_t fixed;
+ dns_name_t *name = dns_fixedname_initname(&fixed);
+ isc_buffer_t buffer;
+ char *newline = NULL, *domain = pos;
+ size_t len;
+
pos += strcspn(pos, "\r\n");
- char *newline = pos;
+ newline = pos;
pos += strspn(pos, "\r\n");
- size_t len = newline - domain;
+
+ len = newline - domain;
domain[len] = '\0';
- dns_fixedname_t fixed;
- dns_name_t *name = dns_fixedname_initname(&fixed);
- isc_buffer_t buffer;
isc_buffer_init(&buffer, domain, len);
isc_buffer_add(&buffer, len);
result = dns_name_fromtext(name, &buffer, dns_rootname, 0,
NULL);
- void *pval = NULL;
- uint32_t ival = 0;
if (result == ISC_R_SUCCESS) {
smallname_from_name(name, &pval, &ival);
result = dns_qp_insert(qp, pval, ival);
}
dns_qp_compact(qp, DNS_QPGC_ALL);
- size_t smallbytes = wirebytes + labels + names * sizeof(isc_refcount_t);
- dns_qp_memusage_t memusage = dns_qp_memusage(qp);
- uint64_t compaction_us, recovery_us, rollback_us;
- dns_qp_gctime(&compaction_us, &recovery_us, &rollback_us);
-
#define print_megabytes(label, value) \
printf("%6.2f MiB - " label "\n", (double)(value) / 1048576.0)
if (!dumptxt && !dumpdot) {
+ size_t smallbytes = wirebytes + labels +
+ names * sizeof(isc_refcount_t);
+ dns_qp_memusage_t memusage = dns_qp_memusage(qp);
+ uint64_t compaction_us, recovery_us, rollback_us;
+ dns_qp_gctime(&compaction_us, &recovery_us, &rollback_us);
+
printf("leaves %zu\n"
" nodes %zu\n"
" used %zu\n"
printf("%6zu - max key len\n", qp_test_maxkeylen(qp));
}
- if (dumptxt)
+ if (dumptxt) {
qp_test_dumptrie(qp);
- if (dumpdot)
+ }
+ if (dumpdot) {
qp_test_dumpdot(qp);
+ }
return (0);
}
dns_qpkey_t key;
} *item;
-static uint32_t
+static void
item_refcount(void *ctx, void *pval, uint32_t ival) {
UNUSED(ctx);
UNUSED(pval);
UNUSED(ival);
- return (1);
}
static size_t
strlcpy(buf, "bench", size);
}
-const struct dns_qpmethods item_methods = {
+const dns_qpmethods_t item_methods = {
item_refcount,
item_refcount,
item_makekey,
void *pval = NULL;
uint32_t ival = ~0U;
dns_qp_t *qp = NULL;
-
size_t bytes = ITEM_COUNT * sizeof(*item);
+ uint64_t start;
+ start = isc_time_monotonic();
item = isc_mem_allocatex(mctx, bytes, ISC_MEM_ZERO);
- uint64_t start = isc_time_monotonic();
-
/* ensure there are no duplicate names */
dns_qp_create(mctx, &item_methods, NULL, &qp);
for (size_t i = 0; i < ITEM_COUNT; i++) {
static void
next_loop(struct thread_args *args, isc_nanosecs_t start) {
isc_nanosecs_t stop = isc_time_monotonic();
+
args->worked += stop - start;
args->stop = stop;
if (args->stop - args->start < RUNTIME) {
static void
read_zipf(uv_idle_t *idle) {
struct thread_args *args = idle->data;
+ isc_nanosecs_t start;
+ void *pval = NULL;
+ uint32_t ival;
/* outside time because it is v slow */
uint32_t r[args->tx_per_loop][args->ops_per_tx];
}
}
- isc_nanosecs_t start = isc_time_monotonic();
- void *pval;
- uint32_t ival;
-
+ start = isc_time_monotonic();
for (uint32_t tx = 0; tx < args->tx_per_loop; tx++) {
args->transactions++;
dns_qpread_t qp;
read_transactions(uv_idle_t *idle) {
struct thread_args *args = idle->data;
isc_nanosecs_t start = isc_time_monotonic();
- void *pval;
+ void *pval = NULL;
uint32_t ival;
for (uint32_t tx = 0; tx < args->tx_per_loop; tx++) {
load_multi(struct bench_state *bctx) {
dns_qp_t *qp = NULL;
size_t count = 0;
-
- uint64_t start = isc_time_monotonic();
+ uint64_t start;
dns_qpmulti_create(bctx->mctx, bctx->loopmgr, &item_methods, NULL,
&bctx->multi);
/* initial contents of the trie */
+ start = isc_time_monotonic();
dns_qpmulti_update(bctx->multi, &qp);
for (size_t i = 0; i < bctx->max_item; i++) {
if (isc_random_uniform(2) == 0) {
static void
collect(void *varg) {
- TRACE("");
-
struct thread_args *args = varg;
struct bench_state *bctx = args->bctx;
struct thread_args *thread = bctx->thread;
+ struct {
+ uint64_t worked, txns, ops, compactions;
+ } stats[2] = {};
+ double load_time = bctx->load_time;
+ double elapsed = 0, mut_work, readers, read_work, elapsed_ms;
+ uint32_t nloops;
+ bool zipf;
+
+ TRACE("collect");
bctx->waiting--;
if (bctx->waiting > 0) {
}
isc_barrier_destroy(&bctx->barrier);
- struct {
- uint64_t worked, txns, ops, compactions;
- } stats[2] = {};
-
- double load_time = bctx->load_time;
load_time = load_time > 0 ? load_time / (double)NS_PER_SEC : NAN;
- double elapsed = 0;
- bool zipf = bctx->mutate == 0 && bctx->readers == 0;
- uint32_t nloops = zipf ? bctx->nloops : bctx->readers + bctx->mutate;
+ zipf = bctx->mutate == 0 && bctx->readers == 0;
+ nloops = zipf ? bctx->nloops : bctx->readers + bctx->mutate;
for (uint32_t t = 0; t < nloops; t++) {
struct thread_args *tp = &thread[t];
elapsed = ISC_MAX(elapsed, (tp->stop - tp->start));
bool mut = t < bctx->mutate;
+
stats[mut].worked += tp->worked;
stats[mut].txns += tp->transactions;
stats[mut].ops += tp->transactions * tp->ops_per_tx;
printf("%7.2f\t", (double)bctx->qp_bytes / bctx->qp_items);
printf("%7u\t", bctx->max_item);
- double mut_work = stats[1].worked / (double)US_PER_MS;
+ mut_work = stats[1].worked / (double)US_PER_MS;
printf("%7u\t", bctx->mutate);
printf("%7u\t", bctx->mut_tx_per_loop);
printf("%7u\t", bctx->mut_ops_per_tx);
printf("%7.2f\t", stats[1].txns / mut_work);
printf("%7.2f\t", stats[1].ops / mut_work);
- double readers = zipf ? bctx->nloops - bctx->mutate : bctx->readers;
- double read_work = stats[0].worked / (double)US_PER_MS;
- double elapsed_ms = elapsed / (double)US_PER_MS;
+ readers = zipf ? bctx->nloops - bctx->mutate : bctx->readers;
+ read_work = stats[0].worked / (double)US_PER_MS;
+ elapsed_ms = elapsed / (double)US_PER_MS;
printf("%7u\t", bctx->readers);
printf("%7u\t", bctx->read_tx_per_loop);
printf("%7u\t", bctx->read_ops_per_tx);
isc_loop_t *loop = isc_loop_current(loopmgr);
isc_mem_t *mctx = isc_loop_getmctx(loop);
uint32_t nloops = isc_loopmgr_nloops(loopmgr);
-
size_t bytes = sizeof(struct bench_state) +
sizeof(struct thread_args) * nloops;
-
struct bench_state *bctx = isc_mem_getx(mctx, bytes, ISC_MEM_ZERO);
*bctx = (struct bench_state){
main(void) {
isc_loopmgr_t *loopmgr = NULL;
isc_mem_t *mctx = NULL;
-
uint32_t nloops;
const char *env_workers = getenv("ISC_TASK_WORKERS");
+
if (env_workers != NULL) {
nloops = atoi(env_workers);
} else {
#define ITER_ITEMS 100
-static uint32_t
+static void
check_leaf(void *uctx, void *pval, uint32_t ival) {
uint32_t *items = uctx;
assert_in_range(ival, 1, ITER_ITEMS - 1);
assert_ptr_equal(items + ival, pval);
- return (1);
}
static size_t
UNUSED(size);
}
-const struct dns_qpmethods qpiter_methods = {
+const dns_qpmethods_t qpiter_methods = {
check_leaf,
check_leaf,
qpiter_makekey,
dns_qp_destroy(&qp);
}
-static uint32_t
+static void
no_op(void *uctx, void *pval, uint32_t ival) {
UNUSED(uctx);
UNUSED(pval);
UNUSED(ival);
- return (1);
}
static size_t
return (dns_qpkey_fromname(key, dns_fixedname_name(&fixed)));
}
-const struct dns_qpmethods string_methods = {
+const dns_qpmethods_t string_methods = {
no_op,
no_op,
qpkey_fromstring,
dns_qpkey_t ascii;
} item[ITEM_COUNT];
-static uint32_t
+static void
item_attach(void *ctx, void *pval, uint32_t ival) {
- assert_null(ctx);
- assert_ptr_equal(pval, &item[ival]);
- return (item[ival].refcount++);
+ INSIST(ctx == NULL);
+ INSIST(pval == &item[ival]);
+ item[ival].refcount++;
}
-static uint32_t
+static void
item_detach(void *ctx, void *pval, uint32_t ival) {
assert_null(ctx);
assert_ptr_equal(pval, &item[ival]);
assert_int_not_equal(item[ival].refcount, 0);
- return (item[ival].refcount--);
+ item[ival].refcount--;
}
static size_t
strlcpy(buf, "test", size);
}
-const struct dns_qpmethods test_methods = {
+const dns_qpmethods_t test_methods = {
item_attach,
item_detach,
item_makekey,