static void check_iteration(ck_bitmap_t *bits, unsigned int len, bool initial) { ck_bitmap_iterator_t iter; unsigned int i = 0, j; len += 1; if (initial == true) { if (bits == g_bits) len = length; else len = STATIC_LENGTH; } ck_bitmap_iterator_init(&iter, bits); for (j = 0; ck_bitmap_next(bits, &iter, &i) == true; j++) { if (i == j) continue; ck_error("[4] ERROR: Expected bit %u, got bit %u\n", j, i); } if (j != len) { ck_error("[5] ERROR: Expected length %u, got length %u\n", len, j); } return; }
int main(int argc, char *argv[]) { int i, r; struct context *context; pthread_t *thread; if (argc != 4) { ck_error("Usage: validate <threads> <affinity delta> <size>\n"); } a.request = 0; a.delta = atoi(argv[2]); nthr = atoi(argv[1]); assert(nthr >= 1); size = atoi(argv[3]); assert(size > 0); fifo = malloc(sizeof(ck_fifo_spsc_t) * nthr); assert(fifo); context = malloc(sizeof(*context) * nthr); assert(context); thread = malloc(sizeof(pthread_t) * nthr); assert(thread); for (i = 0; i < nthr; i++) { ck_fifo_spsc_entry_t *garbage; context[i].tid = i; if (i == 0) { context[i].previous = nthr - 1; context[i].next = i + 1; } else if (i == nthr - 1) { context[i].next = 0; context[i].previous = i - 1; } else { context[i].next = i + 1; context[i].previous = i - 1; } ck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t))); ck_fifo_spsc_deinit(fifo + i, &garbage); if (garbage == NULL) ck_error("ERROR: Expected non-NULL stub node on deinit.\n"); free(garbage); ck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t))); r = pthread_create(thread + i, NULL, test, context + i); assert(r == 0); } for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); return (0); }
int main(int argc, char *argv[]) { int d; pthread_t *p; uint64_t *latency; if (argc != 3) { ck_error("Usage: throughput <delta> <threads>\n"); } threads = atoi(argv[2]); if (threads <= 0) { ck_error("ERROR: Threads must be a value > 0.\n"); } p = malloc(sizeof(pthread_t) * threads); if (p == NULL) { ck_error("ERROR: Failed to initialize thread.\n"); } latency = malloc(sizeof(uint64_t) * threads); if (latency == NULL) { ck_error("ERROR: Failed to create latency buffer.\n"); } d = atoi(argv[1]); rwlock_test(p, d, latency, thread_lock, "rwlock"); #ifdef CK_F_PR_RTM rwlock_test(p, d, latency, thread_lock_rtm, "rwlock, rtm"); #endif /* CK_F_PR_RTM */ return 0; }
static void * test(void *c) { struct context *context = c; struct entry *entry; ck_fifo_spsc_entry_t *fifo_entry; int i, j; if (aff_iterate(&a)) { perror("ERROR: Could not affine thread"); exit(EXIT_FAILURE); } #ifdef DEBUG fprintf(stderr, "%p %u: %u -> %u\n", fifo+context->tid, context->tid, context->previous, context->tid); #endif if (context->tid == 0) { struct entry *entries; entries = malloc(sizeof(struct entry) * size); assert(entries != NULL); for (i = 0; i < size; i++) { entries[i].value = i; entries[i].tid = 0; fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entries + i); } } ck_pr_inc_uint(&barrier); while (ck_pr_load_uint(&barrier) < (unsigned int)nthr); for (i = 0; i < ITERATIONS; i++) { for (j = 0; j < size; j++) { while (ck_fifo_spsc_dequeue(fifo + context->previous, &entry) == false); if (context->previous != (unsigned int)entry->tid) { ck_error("T [%u:%p] %u != %u\n", context->tid, (void *)entry, entry->tid, context->previous); } if (entry->value != j) { ck_error("V [%u:%p] %u != %u\n", context->tid, (void *)entry, entry->value, j); } entry->tid = context->tid; fifo_entry = ck_fifo_spsc_recycle(fifo + context->tid); if (fifo_entry == NULL) fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entry); } } return (NULL); }
int main(int argc, char *argv[]) { unsigned int bytes, base; if (argc >= 2) { length = atoi(argv[1]); } base = ck_bitmap_base(length); bytes = ck_bitmap_size(length); fprintf(stderr, "Configuration: %u bytes\n", bytes); g_bits = malloc(bytes); memset(g_bits->map, 0xFF, base); ck_bitmap_init(g_bits, length, false); test(g_bits, length, false); memset(g_bits->map, 0x00, base); ck_bitmap_init(g_bits, length, true); test(g_bits, length, true); ck_bitmap_test(g_bits, length - 1); CK_BITMAP_INSTANCE(STATIC_LENGTH) sb; fprintf(stderr, "Static configuration: %zu bytes\n", sizeof(sb)); memset(CK_BITMAP_BUFFER(&sb), 0xFF, ck_bitmap_base(STATIC_LENGTH)); CK_BITMAP_INIT(&sb, STATIC_LENGTH, false); test(CK_BITMAP(&sb), STATIC_LENGTH, false); memset(CK_BITMAP_BUFFER(&sb), 0x00, ck_bitmap_base(STATIC_LENGTH)); CK_BITMAP_INIT(&sb, STATIC_LENGTH, true); test(CK_BITMAP(&sb), STATIC_LENGTH, true); CK_BITMAP_CLEAR(&sb); if (CK_BITMAP_TEST(&sb, 1) == true) { ck_error("ERROR: Expected bit to be reset.\n"); } CK_BITMAP_SET(&sb, 1); if (CK_BITMAP_TEST(&sb, 1) == false) { ck_error("ERROR: Expected bit to be set.\n"); } CK_BITMAP_RESET(&sb, 1); if (CK_BITMAP_TEST(&sb, 1) == true) { ck_error("ERROR: Expected bit to be reset.\n"); } return 0; }
int main(int argc, char *argv[]) { int t; pthread_t *p; uint64_t *latency; if (argc != 3) { ck_error("Usage: throughput <delta> <threads>\n"); } threads = atoi(argv[2]); if (threads <= 0) { ck_error("ERROR: Threads must be a value > 0.\n"); } p = malloc(sizeof(pthread_t) * threads); if (p == NULL) { ck_error("ERROR: Failed to initialize thread.\n"); } latency = malloc(sizeof(uint64_t) * threads); if (latency == NULL) { ck_error("ERROR: Failed to create latency buffer.\n"); } affinity.delta = atoi(argv[1]); affinity.request = 0; fprintf(stderr, "Creating threads (brlock)..."); for (t = 0; t < threads; t++) { if (pthread_create(&p[t], NULL, thread_brlock, latency + t) != 0) { ck_error("ERROR: Could not create thread %d\n", t); } } fprintf(stderr, "done\n"); sleep(10); ck_pr_store_uint(&flag, 1); fprintf(stderr, "Waiting for threads to finish acquisition regression..."); for (t = 0; t < threads; t++) pthread_join(p[t], NULL); fprintf(stderr, "done\n\n"); for (t = 1; t <= threads; t++) printf("%10u %20" PRIu64 "\n", t, latency[t - 1]); return (0); }
static void rwlock_test(pthread_t *p, int d, uint64_t *latency, void *(*f)(void *), const char *label) { int t; ck_pr_store_int(&barrier, 0); ck_pr_store_uint(&flag, 0); affinity.delta = d; affinity.request = 0; fprintf(stderr, "Creating threads (%s)...", label); for (t = 0; t < threads; t++) { if (pthread_create(&p[t], NULL, f, latency + t) != 0) { ck_error("ERROR: Could not create thread %d\n", t); } } fprintf(stderr, "done\n"); common_sleep(10); ck_pr_store_uint(&flag, 1); fprintf(stderr, "Waiting for threads to finish acquisition regression..."); for (t = 0; t < threads; t++) pthread_join(p[t], NULL); fprintf(stderr, "done\n\n"); for (t = 1; t <= threads; t++) printf("%10u %20" PRIu64 "\n", t, latency[t - 1]); fprintf(stderr, "\n"); return; }
static void validate(struct example *copy) { if (copy->b != copy->a + 1000) { ck_error("ERROR: Failed regression: copy->b (%u != %u + %u / %u)\n", copy->b, copy->a, 1000, copy->a + 1000); } if (copy->c != copy->a + copy->b) { ck_error("ERROR: Failed regression: copy->c (%u != %u + %u / %u)\n", copy->c, copy->a, copy->b, copy->a + copy->b); } return; }
static void * thread(void *b) { ck_barrier_mcs_t *barrier = b; ck_barrier_mcs_state_t state; int j, counter; int i = 0; aff_iterate(&a); ck_barrier_mcs_subscribe(barrier, &state); ck_pr_inc_int(&barrier_wait); while (ck_pr_load_int(&barrier_wait) != nthr) ck_pr_stall(); for (j = 0; j < ITERATE; j++) { i = j++ & (ENTRIES - 1); ck_pr_inc_int(&counters[i]); ck_barrier_mcs(barrier, &state); counter = ck_pr_load_int(&counters[i]); if (counter != nthr * (j / ENTRIES + 1)) { ck_error("FAILED [%d:%d]: %d != %d\n", i, j - 1, counter, nthr); } } return (NULL); }
int main(void) { #if defined(CK_F_PR_STORE_DOUBLE) && defined(CK_F_PR_LOAD_DOUBLE) double d; ck_pr_store_double(&d, 0.0); if (ck_pr_load_double(&d) != 0.0) { ck_error("Stored 0 in double, did not find 0.\n"); } #endif common_srand((unsigned int)getpid()); #ifdef CK_F_PR_STORE_64 CK_PR_STORE_B(64); #endif #ifdef CK_F_PR_STORE_32 CK_PR_STORE_B(32); #endif #ifdef CK_F_PR_STORE_16 CK_PR_STORE_B(16); #endif #ifdef CK_F_PR_STORE_8 CK_PR_STORE_B(8); #endif return (0); }
int main(int argc, char *argv[]) { unsigned int r, size; common_srand48((long int)time(NULL)); if (argc < 2) { ck_error("Usage: ck_hs <dictionary> [<repetitions> <initial size>]\n"); } r = 16; if (argc >= 3) r = atoi(argv[2]); size = 8; if (argc >= 4) size = atoi(argv[3]); global_seed = common_lrand48(); run_test(argv[1], r, size, 0); run_test(argv[1], r, size, CK_HS_MODE_DELETE); fprintf(stderr, "# reverse_insertion serial_insertion random_insertion serial_swap " "serial_replace reverse_get serial_get random_get serial_remove negative_get tombstone " "set_unique gc rebuild\n\n"); return 0; }
int main(int argc, char *argv[]) { pthread_t *threads; ck_barrier_mcs_t *barrier; int i; if (argc < 3) { ck_error("Usage: correct <number of threads> <affinity delta>\n"); } nthr = atoi(argv[1]); if (nthr <= 0) { ck_error("ERROR: Number of threads must be greater than 0\n"); } threads = malloc(sizeof(pthread_t) * nthr); if (threads == NULL) { ck_error("ERROR: Could not allocate thread structures\n"); } barrier = malloc(sizeof(ck_barrier_mcs_t) * nthr); if (barrier == NULL) { ck_error("ERROR: Could not allocate barrier structures\n"); } ck_barrier_mcs_init(barrier, nthr); a.delta = atoi(argv[2]); fprintf(stderr, "Creating threads (barrier)..."); for (i = 0; i < nthr; i++) { if (pthread_create(&threads[i], NULL, thread, barrier)) { ck_error("ERROR: Could not create thread %d\n", i); } } fprintf(stderr, "done\n"); fprintf(stderr, "Waiting for threads to finish correctness regression..."); for (i = 0; i < nthr; i++) pthread_join(threads[i], NULL); fprintf(stderr, "done (passed)\n"); return (0); }
static void * test_unique(void *key, void *closure) { if (key != NULL) ck_error("ERROR: Apply callback expects NULL argument instead of [%s]\n", key); return closure; }
int main(int argc, char *argv[]) { pthread_t *threads; struct block *context; int i; if (argc != 3) { ck_error("Usage: correct <number of threads> <affinity delta>\n"); } nthr = atoi(argv[1]); if (nthr <= 0) { ck_error("ERROR: Number of threads must be greater than 0\n"); } threads = malloc(sizeof(pthread_t) * nthr); if (threads == NULL) { ck_error("ERROR: Could not allocate thread structures\n"); } context = malloc(sizeof(struct block) * nthr); if (context == NULL) { ck_error("ERROR: Could not allocate thread contexts\n"); } a.delta = atoi(argv[2]); fprintf(stderr, "Creating threads (mutual exclusion)..."); for (i = 0; i < nthr; i++) { context[i].tid = i + 1; if (pthread_create(&threads[i], NULL, thread, context + i)) { ck_error("ERROR: Could not create thread %d\n", i); } } fprintf(stderr, "done\n"); fprintf(stderr, "Waiting for threads to finish correctness regression..."); for (i = 0; i < nthr; i++) pthread_join(threads[i], NULL); fprintf(stderr, "done (passed)\n"); return (0); }
int main(int argc, char *argv[]) { int i, r; void *buffer; struct context *context; pthread_t *thread; if (argc != 4) { ck_error("Usage: validate <threads> <affinity delta> <size>\n"); } a.request = 0; a.delta = atoi(argv[2]); nthr = atoi(argv[1]); assert(nthr >= 1); size = atoi(argv[3]); assert(size > 4 && (size & size - 1) == 0); size -= 1; ring = malloc(sizeof(ck_ring_t) * nthr); assert(ring); context = malloc(sizeof(*context) * nthr); assert(context); thread = malloc(sizeof(pthread_t) * nthr); assert(thread); for (i = 0; i < nthr; i++) { context[i].tid = i; if (i == 0) { context[i].previous = nthr - 1; context[i].next = i + 1; } else if (i == nthr - 1) { context[i].next = 0; context[i].previous = i - 1; } else { context[i].next = i + 1; context[i].previous = i - 1; } buffer = malloc(sizeof(void *) * (size + 1)); assert(buffer); ck_ring_init(ring + i, buffer, size + 1); r = pthread_create(thread + i, NULL, test, context + i); assert(r == 0); } for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); return (0); }
static void * test_negative(void *key, void *closure) { (void)closure; if (key != NULL) ck_error("ERROR: Apply callback expects NULL argument instead of [%s]\n", key); return NULL; }
static void test(ck_bitmap_t *bits, unsigned int n_length, bool initial) { unsigned int i; CK_BITMAP_INSTANCE(8) u; CK_BITMAP_INIT(&u, 8, false); CK_BITMAP_SET(&u, 1); CK_BITMAP_SET(&u, 4); for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == !initial) { ck_error("[0] ERROR [%u]: Expected %u got %u\n", i, initial, !initial); } } for (i = 0; i < n_length; i++) { ck_bitmap_set(bits, i); if (ck_bitmap_test(bits, i) == false) { ck_error("[1] ERROR: Expected bit to be set: %u\n", i); } ck_bitmap_reset(bits, i); if (ck_bitmap_test(bits, i) == true) { ck_error("[2] ERROR: Expected bit to be cleared: %u\n", i); } ck_bitmap_set(bits, i); if (ck_bitmap_test(bits, i) == false) { ck_error("[3] ERROR: Expected bit to be set: %u\n", i); } check_iteration(bits, i, initial); } for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == false) { ck_error("[4] ERROR: Expected bit to be set: %u\n", i); } } ck_bitmap_clear(bits); for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == true) { ck_error("[4] ERROR: Expected bit to be reset: %u\n", i); } } ck_bitmap_union(bits, CK_BITMAP(&u)); if (ck_bitmap_test(bits, 1) == false || ck_bitmap_test(bits, 4) == false) { ck_error("ERROR: Expected union semantics.\n"); } return; }
static void * test_ip(void *key, void *closure) { const char *a = key; const char *b = closure; if (strcmp(a, b) != 0) ck_error("Mismatch: %s != %s\n", a, b); return closure; }
int main(void) { ck_hp_record_t record; ck_stack_entry_t entry[ENTRIES]; uint64_t s, e, a; unsigned int i; unsigned int j; void *r; ck_hp_init(&stack_hp, CK_HP_STACK_SLOTS_COUNT, 1000000, NULL); r = malloc(CK_HP_STACK_SLOTS_SIZE); if (r == NULL) { ck_error("ERROR: Failed to allocate slots.\n"); } ck_hp_register(&stack_hp, &record, (void *)r); a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_hp_stack_push_mpmc(&stack, entry + j); e = rdtsc(); a += e - s; } printf("ck_hp_stack_push_mpmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); for (j = 0; j < ENTRIES; j++) ck_hp_stack_push_mpmc(&stack, entry + j); s = rdtsc(); for (j = 0; j < ENTRIES; j++) { r = ck_hp_stack_pop_mpmc(&record, &stack); } e = rdtsc(); a += e - s; } printf(" ck_hp_stack_pop_mpmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); return 0; }
int main(void) { void *r; uint64_t s, e, a; unsigned int i; unsigned int j; ck_hp_fifo_entry_t hp_entry[ENTRIES]; ck_hp_fifo_entry_t hp_stub; ck_hp_record_t record; ck_hp_init(&fifo_hp, CK_HP_FIFO_SLOTS_COUNT, 1000000, NULL); r = malloc(CK_HP_FIFO_SLOTS_SIZE); if (r == NULL) { ck_error("ERROR: Failed to allocate slots.\n"); } ck_hp_register(&fifo_hp, &record, r); a = 0; for (i = 0; i < STEPS; i++) { ck_hp_fifo_init(&fifo, &hp_stub); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_hp_fifo_enqueue_mpmc(&record, &fifo, hp_entry + j, NULL); e = rdtsc(); a += e - s; } printf("ck_hp_fifo_enqueue_mpmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); a = 0; for (i = 0; i < STEPS; i++) { ck_hp_fifo_init(&fifo, &hp_stub); for (j = 0; j < ENTRIES; j++) ck_hp_fifo_enqueue_mpmc(&record, &fifo, hp_entry + j, NULL); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_hp_fifo_dequeue_mpmc(&record, &fifo, &r); e = rdtsc(); a += e - s; } printf("ck_hp_fifo_dequeue_mpmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); return 0; }
int main(int argc, char *argv[]) { int i, r; struct context *context; pthread_t *thread; int threshold; if (argc != 5) { ck_error("Usage: validate <threads> <affinity delta> <size> <threshold>\n"); } a.delta = atoi(argv[2]); nthr = atoi(argv[1]); assert(nthr >= 1); size = atoi(argv[3]); assert(size > 0); threshold = atoi(argv[4]); assert(threshold > 0); context = malloc(sizeof(*context) * nthr); assert(context); thread = malloc(sizeof(pthread_t) * nthr); assert(thread); ck_hp_init(&fifo_hp, 2, threshold, destructor); ck_hp_fifo_init(&fifo, malloc(sizeof(ck_hp_fifo_entry_t))); for (i = 0; i < nthr; i++) { context[i].tid = i; r = pthread_create(thread + i, NULL, test, context + i); assert(r == 0); } for (i = 0; i < nthr; i++) pthread_join(thread[i], NULL); return (0); }
static void test(ck_bitmap_t *bits, unsigned int n_length, bool initial) { unsigned int i; for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == !initial) { ck_error("[0] ERROR [%u]: Expected %u got %u\n", i, initial, !initial); } } for (i = 0; i < n_length; i++) { ck_bitmap_set_mpmc(bits, i); if (ck_bitmap_test(bits, i) == false) { ck_error("[1] ERROR: Expected bit to be set: %u\n", i); } ck_bitmap_reset_mpmc(bits, i); if (ck_bitmap_test(bits, i) == true) { ck_error("[2] ERROR: Expected bit to be cleared: %u\n", i); } ck_bitmap_set_mpmc(bits, i); if (ck_bitmap_test(bits, i) == false) { ck_error("[3] ERROR: Expected bit to be set: %u\n", i); } check_iteration(bits, i, initial); } for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == false) { ck_error("[4] ERROR: Expected bit to be set: %u\n", i); } } ck_bitmap_clear(bits); for (i = 0; i < n_length; i++) { if (ck_bitmap_test(bits, i) == true) { ck_error("[4] ERROR: Expected bit to be reset: %u\n", i); } } return; }
static void * thread(void *null) { struct block *context = null; int i = ITERATE; unsigned int l; if (aff_iterate(&a)) { perror("ERROR: Could not affine thread"); exit(EXIT_FAILURE); } if (context->tid == (unsigned int)nthr - 1) context->tid = sizeof(lock.readers) + 1; while (i--) { ck_bytelock_write_lock(&lock, context->tid); { l = ck_pr_load_uint(&locked); if (l != 0) { ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l); } ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); ck_pr_inc_uint(&locked); l = ck_pr_load_uint(&locked); if (l != 8) { ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l); } ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); ck_pr_dec_uint(&locked); l = ck_pr_load_uint(&locked); if (l != 0) { ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l); } } ck_bytelock_write_unlock(&lock); ck_bytelock_read_lock(&lock, context->tid); { l = ck_pr_load_uint(&locked); if (l != 0) { ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l); } } ck_bytelock_read_unlock(&lock, context->tid); } return (NULL); }
int main(int argc, char *argv[]) { FILE *fp; char buffer[512]; size_t i, j, r; unsigned int d = 0; uint64_t s, e, a, ri, si, ai, sr, rg, sg, ag, sd, ng; char **t; struct ck_ht_stat st; r = 20; s = 8; srand(time(NULL)); if (argc < 2) { ck_error("Usage: ck_ht <dictionary> [<repetitions> <initial size>]\n"); } if (argc >= 3) r = atoi(argv[2]); if (argc >= 4) s = (uint64_t)atoi(argv[3]); keys = malloc(sizeof(char *) * keys_capacity); assert(keys != NULL); fp = fopen(argv[1], "r"); assert(fp != NULL); while (fgets(buffer, sizeof(buffer), fp) != NULL) { buffer[strlen(buffer) - 1] = '\0'; keys[keys_length++] = strdup(buffer); assert(keys[keys_length - 1] != NULL); if (keys_length == keys_capacity) { t = realloc(keys, sizeof(char *) * (keys_capacity *= 2)); assert(t != NULL); keys = t; } } t = realloc(keys, sizeof(char *) * keys_length); assert(t != NULL); keys = t; table_init(); for (i = 0; i < keys_length; i++) d += table_insert(keys[i]) == false; ck_ht_stat(&ht, &st); fprintf(stderr, "# %zu entries stored, %u duplicates, %" PRIu64 " probe.\n", table_count(), d, st.probe_maximum); fprintf(stderr, "# reverse_insertion serial_insertion random_insertion serial_replace reverse_get serial_get random_get serial_remove negative_get\n\n"); a = 0; for (j = 0; j < r; j++) { if (table_reset() == false) { ck_error("ERROR: Failed to reset hash table.\n"); } s = rdtsc(); for (i = keys_length; i > 0; i--) d += table_insert(keys[i - 1]) == false; e = rdtsc(); a += e - s; } ri = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { if (table_reset() == false) { ck_error("ERROR: Failed to reset hash table.\n"); } s = rdtsc(); for (i = 0; i < keys_length; i++) d += table_insert(keys[i]) == false; e = rdtsc(); a += e - s; } si = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { keys_shuffle(keys); if (table_reset() == false) { ck_error("ERROR: Failed to reset hash table.\n"); } s = rdtsc(); for (i = 0; i < keys_length; i++) d += table_insert(keys[i]) == false; e = rdtsc(); a += e - s; } ai = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { s = rdtsc(); for (i = 0; i < keys_length; i++) table_replace(keys[i]); e = rdtsc(); a += e - s; } sr = a / (r * keys_length); table_reset(); for (i = 0; i < keys_length; i++) table_insert(keys[i]); a = 0; for (j = 0; j < r; j++) { s = rdtsc(); for (i = keys_length; i > 0; i--) { if (table_get(keys[i - 1]) == NULL) { ck_error("ERROR: Unexpected NULL value.\n"); } } e = rdtsc(); a += e - s; } rg = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { s = rdtsc(); for (i = 0; i < keys_length; i++) { if (table_get(keys[i]) == NULL) { ck_error("ERROR: Unexpected NULL value.\n"); } } e = rdtsc(); a += e - s; } sg = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { keys_shuffle(keys); s = rdtsc(); for (i = 0; i < keys_length; i++) { if (table_get(keys[i]) == NULL) { ck_error("ERROR: Unexpected NULL value.\n"); } } e = rdtsc(); a += e - s; } ag = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { s = rdtsc(); for (i = 0; i < keys_length; i++) table_remove(keys[i]); e = rdtsc(); a += e - s; for (i = 0; i < keys_length; i++) table_insert(keys[i]); } sd = a / (r * keys_length); a = 0; for (j = 0; j < r; j++) { s = rdtsc(); for (i = 0; i < keys_length; i++) { table_get("\x50\x03\x04\x05\x06\x10"); } e = rdtsc(); a += e - s; } ng = a / (r * keys_length); printf("%zu " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 " " "%" PRIu64 "\n", keys_length, ri, si, ai, sr, rg, sg, ag, sd, ng); return 0; }
static void * test(void *c) { struct context *context = c; struct entry *entry; int i, j; bool r; ck_barrier_centralized_state_t sense = CK_BARRIER_CENTRALIZED_STATE_INITIALIZER; if (aff_iterate(&a)) { perror("ERROR: Could not affine thread"); exit(EXIT_FAILURE); } if (context->tid == 0) { struct entry *entries; entries = malloc(sizeof(struct entry) * size); assert(entries != NULL); if (ck_ring_size(ring) != 0) { ck_error("More entries than expected: %u > 0\n", ck_ring_size(ring)); } for (i = 0; i < size; i++) { entries[i].value = i; entries[i].tid = 0; r = ck_ring_enqueue_spsc(ring, entries + i); assert(r != false); } if (ck_ring_size(ring) != (unsigned int)size) { ck_error("Less entries than expected: %u < %d\n", ck_ring_size(ring), size); } if (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) { ck_error("Capacity less than expected: %u < %u\n", ck_ring_size(ring), ck_ring_capacity(ring)); } } ck_barrier_centralized(&barrier, &sense, nthr); for (i = 0; i < ITERATIONS; i++) { for (j = 0; j < size; j++) { while (ck_ring_dequeue_spsc(ring + context->previous, &entry) == false); if (context->previous != (unsigned int)entry->tid) { ck_error("[%u:%p] %u != %u\n", context->tid, (void *)entry, entry->tid, context->previous); } if (entry->value != j) { ck_error("[%u:%p] %u != %u\n", context->tid, (void *)entry, entry->tid, context->previous); } entry->tid = context->tid; r = ck_ring_enqueue_spsc(ring + context->tid, entry); assert(r == true); } } return NULL; }
static void run_test(unsigned int is, unsigned int ad) { ck_hs_t hs[16]; const size_t size = sizeof(hs) / sizeof(*hs); size_t i, j; const char *blob = "#blobs"; unsigned long h; if (ck_hs_init(&hs[0], CK_HS_MODE_SPMC | CK_HS_MODE_OBJECT | ad, hs_hash, hs_compare, &my_allocator, is, 6602834) == false) ck_error("ck_hs_init\n"); for (j = 0; j < size; j++) { for (i = 0; i < sizeof(test) / sizeof(*test); i++) { h = test[i][0]; if (ck_hs_get(&hs[j], h, test[i]) != NULL) { continue; } if (ck_hs_put_unique(&hs[j], h, test[i]) == false) ck_error("ERROR [%zu]: Failed to insert unique (%s)\n", j, test[i]); if (ck_hs_remove(&hs[j], h, test[i]) == false) ck_error("ERROR [%zu]: Failed to remove unique (%s)\n", j, test[i]); break; } if (ck_hs_gc(&hs[j], 0, 0) == false) ck_error("ERROR: Failed to GC empty set.\n"); for (i = 0; i < sizeof(test) / sizeof(*test); i++) { h = test[i][0]; ck_hs_put(&hs[j], h, test[i]); if (ck_hs_put(&hs[j], h, test[i]) == true) { ck_error("ERROR [%u] [1]: put must fail on collision (%s).\n", is, test[i]); } if (ck_hs_get(&hs[j], h, test[i]) == NULL) { ck_error("ERROR [%u]: get must not fail after put\n", is); } } /* Test grow semantics. */ ck_hs_grow(&hs[j], 128); for (i = 0; i < sizeof(test) / sizeof(*test); i++) { h = test[i][0]; if (ck_hs_put(&hs[j], h, test[i]) == true) { ck_error("ERROR [%u] [2]: put must fail on collision.\n", is); } if (ck_hs_get(&hs[j], h, test[i]) == NULL) { ck_error("ERROR [%u]: get must not fail\n", is); } } h = blob[0]; if (ck_hs_get(&hs[j], h, blob) == NULL) { if (j > 0) ck_error("ERROR [%u]: Blob must always exist after first.\n", is); if (ck_hs_put(&hs[j], h, blob) == false) { ck_error("ERROR [%u]: A unique blob put failed.\n", is); } } else { if (ck_hs_put(&hs[j], h, blob) == true) { ck_error("ERROR [%u]: Duplicate blob put succeeded.\n", is); } } /* Grow set and check get semantics. */ ck_hs_grow(&hs[j], 512); for (i = 0; i < sizeof(test) / sizeof(*test); i++) { h = test[i][0]; if (ck_hs_get(&hs[j], h, test[i]) == NULL) { ck_error("ERROR [%u]: get must not fail\n", is); } } /* Delete and check negative membership. */ for (i = 0; i < sizeof(test) / sizeof(*test); i++) { void *r; h = test[i][0]; if (ck_hs_get(&hs[j], h, test[i]) == NULL) continue; if (r = ck_hs_remove(&hs[j], h, test[i]), r == NULL) { ck_error("ERROR [%u]: remove must not fail\n", is); } if (strcmp(r, test[i]) != 0) { ck_error("ERROR [%u]: Removed incorrect node (%s != %s)\n", (char *)r, test[i], is); } } /* Test replacement semantics. */ for (i = 0; i < sizeof(test) / sizeof(*test); i++) { void *r; bool d; h = test[i][0]; d = ck_hs_get(&hs[j], h, test[i]) != NULL; if (ck_hs_set(&hs[j], h, test[i], &r) == false) { ck_error("ERROR [%u]: Failed to set\n", is); } /* Expected replacement. */ if (d == true && (r == NULL || strcmp(r, test[i]) != 0)) { ck_error("ERROR [%u]: Incorrect previous value: %s != %s\n", is, test[i], (char *)r); } /* Replacement should succeed. */ if (ck_hs_fas(&hs[j], h, test[i], &r) == false) ck_error("ERROR [%u]: ck_hs_fas must succeed.\n", is); if (strcmp(r, test[i]) != 0) { ck_error("ERROR [%u]: Incorrect replaced value: %s != %s\n", is, test[i], (char *)r); } if (ck_hs_fas(&hs[j], h, negative, &r) == true) ck_error("ERROR [%u]: Replacement of negative should fail.\n", is); if (ck_hs_set(&hs[j], h, test[i], &r) == false) { ck_error("ERROR [%u]: Failed to set [1]\n", is); } if (strcmp(r, test[i]) != 0) { ck_error("ERROR [%u]: Invalid &hs[j]: %s != %s\n", (char *)r, test[i], is); } } if (j == size - 1) break; if (ck_hs_move(&hs[j + 1], &hs[j], hs_hash, hs_compare, &my_allocator) == false) ck_error("Failed to move hash table"); if (j & 1) { ck_hs_gc(&hs[j + 1], 0, 0); } else { ck_hs_gc(&hs[j + 1], 26, 26); } if (ck_hs_rebuild(&hs[j + 1]) == false) ck_error("Failed to rebuild"); } return; }
int main(void) { size_t i, l; ck_ht_t ht; ck_ht_entry_t entry; ck_ht_hash_t h; ck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER; ck_ht_entry_t *cursor; if (ck_ht_init(&ht, CK_HT_MODE_BYTESTRING, NULL, &my_allocator, 8, 6602834) == false) { perror("ck_ht_init"); exit(EXIT_FAILURE); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_put_spmc(&ht, h, &entry); } l = strlen(test[0]); ck_ht_hash(&h, &ht, test[0], l); ck_ht_entry_set(&entry, h, test[0], l, test[0]); ck_ht_put_spmc(&ht, h, &entry); for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) { ck_error("ERROR (put): Failed to find [%s]\n", test[i]); } else { void *k, *v; k = ck_ht_entry_key(&entry); v = ck_ht_entry_value(&entry); if (strcmp(k, test[i]) || strcmp(v, test[i])) { ck_error("ERROR: Mismatch: (%s, %s) != (%s, %s)\n", (char *)k, (char *)v, test[i], test[i]); } } } ck_ht_hash(&h, &ht, negative, strlen(negative)); ck_ht_entry_key_set(&entry, negative, strlen(negative)); if (ck_ht_get_spmc(&ht, h, &entry) == true) { ck_error("ERROR: Found non-existing entry.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) continue; if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } if (ck_ht_get_spmc(&ht, h, &entry) == true) ck_error("ERROR: Able to find [%s] after delete\n", test[i]); ck_ht_entry_set(&entry, h, test[i], l, test[i]); if (ck_ht_put_spmc(&ht, h, &entry) == false) ck_error("ERROR: Failed to insert [%s]\n", test[i]); if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } } ck_ht_reset_spmc(&ht); if (ck_ht_count(&ht) != 0) { ck_error("ERROR: Map was not reset.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_put_spmc(&ht, h, &entry); } for (i = 0; ck_ht_next(&ht, &iterator, &cursor) == true; i++); if (i != 42) { ck_error("ERROR: Incorrect number of entries in table.\n"); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, test[i]); ck_ht_set_spmc(&ht, h, &entry); } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) { ck_error("ERROR (set): Failed to find [%s]\n", test[i]); } else { void *k, *v; k = ck_ht_entry_key(&entry); v = ck_ht_entry_value(&entry); if (strcmp(k, test[i]) || strcmp(v, test[i])) { ck_error("ERROR: Mismatch: (%s, %s) != (%s, %s)\n", (char *)k, (char *)v, test[i], test[i]); } } } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_set(&entry, h, test[i], l, "REPLACED"); ck_ht_set_spmc(&ht, h, &entry); if (strcmp(test[i], "What") == 0) continue; if (strcmp(test[i], "down.") == 0) continue; if (strcmp(ck_ht_entry_value(&entry), test[i]) != 0) { ck_error("Mismatch detected: %s, expected %s\n", (char *)ck_ht_entry_value(&entry), test[i]); } } ck_ht_iterator_init(&iterator); while (ck_ht_next(&ht, &iterator, &cursor) == true) { if (strcmp(ck_ht_entry_value(cursor), "REPLACED") != 0) { ck_error("Mismatch detected: %s, expected REPLACED\n", (char *)ck_ht_entry_value(cursor)); } } for (i = 0; i < sizeof(test) / sizeof(*test); i++) { l = strlen(test[i]); ck_ht_hash(&h, &ht, test[i], l); ck_ht_entry_key_set(&entry, test[i], l); if (ck_ht_get_spmc(&ht, h, &entry) == false) continue; if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } if (ck_ht_get_spmc(&ht, h, &entry) == true) ck_error("ERROR: Able to find [%s] after delete\n", test[i]); ck_ht_entry_set(&entry, h, test[i], l, test[i]); if (ck_ht_put_spmc(&ht, h, &entry) == false) ck_error("ERROR: Failed to insert [%s]\n", test[i]); if (ck_ht_remove_spmc(&ht, h, &entry) == false) { ck_error("ERROR: Failed to delete existing entry\n"); } } ck_ht_destroy(&ht); if (ck_ht_init(&ht, CK_HT_MODE_DIRECT, NULL, &my_allocator, 8, 6602834) == false) { perror("ck_ht_init"); exit(EXIT_FAILURE); } l = 0; for (i = 0; i < sizeof(direct) / sizeof(*direct); i++) { ck_ht_hash_direct(&h, &ht, direct[i]); ck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)test[i]); l += ck_ht_put_spmc(&ht, h, &entry) == false; } if (l != 7) { ck_error("ERROR: Got %zu failures rather than 7\n", l); } for (i = 0; i < sizeof(direct) / sizeof(*direct); i++) { ck_ht_hash_direct(&h, &ht, direct[i]); ck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)"REPLACED"); l += ck_ht_set_spmc(&ht, h, &entry) == false; } ck_ht_iterator_init(&iterator); while (ck_ht_next(&ht, &iterator, &cursor) == true) { if (strcmp(ck_ht_entry_value(cursor), "REPLACED") != 0) { ck_error("Mismatch detected: %s, expected REPLACED\n", (char *)ck_ht_entry_value(cursor)); } } ck_ht_destroy(&ht); return 0; }
int main(int argc, char *argv[]) { int i, r, size; uint64_t s, e, e_a, d_a; struct entry entry = {0, 0}; ck_ring_buffer_t *buf; ck_ring_t ring; if (argc != 2) { ck_error("Usage: latency <size>\n"); } size = atoi(argv[1]); if (size <= 4 || (size & (size - 1))) { ck_error("ERROR: Size must be a power of 2 greater than 4.\n"); } buf = malloc(sizeof(ck_ring_buffer_t) * size); if (buf == NULL) { ck_error("ERROR: Failed to allocate buffer\n"); } ck_ring_init(&ring, size); e_a = d_a = s = e = 0; for (r = 0; r < ITERATIONS; r++) { for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_enqueue_spsc(&ring, buf, &entry); ck_ring_enqueue_spsc(&ring, buf, &entry); ck_ring_enqueue_spsc(&ring, buf, &entry); ck_ring_enqueue_spsc(&ring, buf, &entry); e = rdtsc(); } e_a += (e - s) / 4; for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_dequeue_spsc(&ring, buf, &entry); ck_ring_dequeue_spsc(&ring, buf, &entry); ck_ring_dequeue_spsc(&ring, buf, &entry); ck_ring_dequeue_spsc(&ring, buf, &entry); e = rdtsc(); } d_a += (e - s) / 4; } printf("spsc %10d %16" PRIu64 " %16" PRIu64 "\n", size, e_a / ITERATIONS, d_a / ITERATIONS); e_a = d_a = s = e = 0; for (r = 0; r < ITERATIONS; r++) { for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_enqueue_spmc(&ring, buf, &entry); ck_ring_enqueue_spmc(&ring, buf, &entry); ck_ring_enqueue_spmc(&ring, buf, &entry); ck_ring_enqueue_spmc(&ring, buf, &entry); e = rdtsc(); } e_a += (e - s) / 4; for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_dequeue_spmc(&ring, buf, &entry); ck_ring_dequeue_spmc(&ring, buf, &entry); ck_ring_dequeue_spmc(&ring, buf, &entry); ck_ring_dequeue_spmc(&ring, buf, &entry); e = rdtsc(); } d_a += (e - s) / 4; } printf("spmc %10d %16" PRIu64 " %16" PRIu64 "\n", size, e_a / ITERATIONS, d_a / ITERATIONS); ck_ring_init(&ring, size); e_a = d_a = s = e = 0; for (r = 0; r < ITERATIONS; r++) { for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_enqueue_mpsc(&ring, buf, &entry); ck_ring_enqueue_mpsc(&ring, buf, &entry); ck_ring_enqueue_mpsc(&ring, buf, &entry); ck_ring_enqueue_mpsc(&ring, buf, &entry); e = rdtsc(); } e_a += (e - s) / 4; for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_dequeue_mpsc(&ring, buf, &entry); ck_ring_dequeue_mpsc(&ring, buf, &entry); ck_ring_dequeue_mpsc(&ring, buf, &entry); ck_ring_dequeue_mpsc(&ring, buf, &entry); e = rdtsc(); } d_a += (e - s) / 4; } printf("mpsc %10d %16" PRIu64 " %16" PRIu64 "\n", size, e_a / ITERATIONS, d_a / ITERATIONS); ck_ring_init(&ring, size); e_a = d_a = s = e = 0; for (r = 0; r < ITERATIONS; r++) { for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_enqueue_mpmc(&ring, buf, &entry); ck_ring_enqueue_mpmc(&ring, buf, &entry); ck_ring_enqueue_mpmc(&ring, buf, &entry); ck_ring_enqueue_mpmc(&ring, buf, &entry); e = rdtsc(); } e_a += (e - s) / 4; for (i = 0; i < size / 4; i += 4) { s = rdtsc(); ck_ring_dequeue_mpmc(&ring, buf, &entry); ck_ring_dequeue_mpmc(&ring, buf, &entry); ck_ring_dequeue_mpmc(&ring, buf, &entry); ck_ring_dequeue_mpmc(&ring, buf, &entry); e = rdtsc(); } d_a += (e - s) / 4; } printf("mpmc %10d %16" PRIu64 " %16" PRIu64 "\n", size, e_a / ITERATIONS, d_a / ITERATIONS); return (0); }
int main(int argc, char** argv) { ck_hp_fifo_entry_t *stub; unsigned long element_count, i; pthread_t *thr; if (argc != 3) { ck_error("Usage: cktest <thread_count> <element_count>\n"); } /* Get element count from argument */ element_count = atoi(argv[2]); /* Get element count from argument */ thread_count = atoi(argv[1]); /* pthread handles */ thr = malloc(sizeof(pthread_t) * thread_count); /* array for local operation count */ count = malloc(sizeof(unsigned long *) * thread_count); /* * Initialize global hazard pointer safe memory reclamation to execute free() * when a fifo_entry is safe to be deleted. * Hazard pointer scan routine will be called when the thread local intern plist's * size exceed 100 entries. */ /* FIFO queue needs 2 hazard pointers */ ck_hp_init(&fifo_hp, CK_HP_FIFO_SLOTS_COUNT, 100, destructor); /* The FIFO requires one stub entry on initialization. */ stub = malloc(sizeof(ck_hp_fifo_entry_t)); /* Behavior is undefined if stub is NULL. */ if (stub == NULL) { exit(EXIT_FAILURE); } /* This is called once to initialize the fifo. */ ck_hp_fifo_init(&fifo, stub); /* Create threads */ for (i = 0; i < thread_count; i++) { count[i] = (element_count + i) / thread_count; if (pthread_create(&thr[i], NULL, queue_50_50, (void *) &count[i]) != 0) { exit(EXIT_FAILURE); } } /* start barrier */ ck_pr_inc_uint(&start_barrier); while (ck_pr_load_uint(&start_barrier) < thread_count + 1); /* end barrier */ ck_pr_inc_uint(&end_barrier); while (ck_pr_load_uint(&end_barrier) < thread_count + 1); /* Join threads */ for (i = 0; i < thread_count; i++) pthread_join(thr[i], NULL); return 0; }
}END_TEST START_TEST(test_div_by_zero2) { ck_error("something goes wrong"); }END_TEST