Ejemplo n.º 1
0
Archivo: order.c Proyecto: binque/ck
static void *
writer_thread(void *unused)
{
	unsigned int i;
	unsigned int iteration = 0;

	(void)unused;

	for (;;) {
		iteration++;
		ck_epoch_write_begin(&epoch_wr);
		for (i = 1; i <= writer_max; i++) {
			if (ck_bag_put_spmc(&bag, (void *)(uintptr_t)i) == false) {
				perror("ck_bag_put_spmc");
				exit(EXIT_FAILURE);
			}

			if (ck_bag_member_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_put_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}
		}

		if (ck_pr_load_int(&leave) == 1)
			break;

		for (i = 1; i < writer_max; i++) {
			void *replace = (void *)(uintptr_t)i;
			if (ck_bag_set_spmc(&bag, (void *)(uintptr_t)i, replace) == false) {
				fprintf(stderr, "ERROR: set %ju != %ju",
						(uintmax_t)(uintptr_t)replace, (uintmax_t)i);
				exit(EXIT_FAILURE);
			}
		}

		for (i = writer_max; i > 0; i--) {
			if (ck_bag_member_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_member_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}

			if (ck_bag_remove_spmc(&bag, (void *)(uintptr_t)i) == false) {
				fprintf(stderr, "ck_bag_remove_spmc [%u]: %u\n", iteration, i);
				exit(EXIT_FAILURE);
			}
		}

		ck_epoch_write_end(&epoch_wr);
	}

	fprintf(stderr, "Writer %u iterations, %u writes per iteration.\n", iteration, writer_max);
	while (ck_pr_load_uint(&barrier) != NUM_READER_THREADS)
		ck_pr_stall();

	ck_pr_inc_uint(&barrier);
	return NULL;
}
Ejemplo n.º 2
0
/*
 * Replace prev_entry with new entry if exists, otherwise insert into bag.
 */
bool
ck_bag_set_spmc(struct ck_bag *bag, void *compare, void *update)
{
	struct ck_bag_block *cursor;
	uint16_t block_index;
	uint16_t n_entries_block = 0;

	cursor = bag->head;
	while (cursor != NULL) {
		n_entries_block = ck_bag_block_count(cursor);
		for (block_index = 0; block_index < n_entries_block; block_index++) {
			if (cursor->array[block_index] != compare)
				continue;

			ck_pr_store_ptr(&cursor->array[block_index], update);
			return true;
		}

		cursor = ck_bag_block_next(cursor->next.ptr);
	}

	return ck_bag_put_spmc(bag, update);
}
Ejemplo n.º 3
0
Archivo: order.c Proyecto: binque/ck
int
main(int argc, char **argv)
{
	pthread_t *readers;
	pthread_t writer;
	unsigned int i, curr;
	void *curr_ptr;
	ck_bag_iterator_t bag_it;
	size_t b = CK_BAG_DEFAULT;

	if (argc >= 2) {
		int r = atoi(argv[1]);
		if (r <= 0) {
			fprintf(stderr, "# entries in block must be > 0\n");
			exit(EXIT_FAILURE);
		}

		b = (size_t)r;
	}

	if (argc >= 3) {
		int r = atoi(argv[2]);
		if (r < 16) {
			fprintf(stderr, "# entries must be >= 16\n");
			exit(EXIT_FAILURE);
		}

		writer_max = (unsigned int)r;
	}

	ck_epoch_init(&epoch_bag, 100);
	ck_epoch_register(&epoch_bag, &epoch_wr);
	ck_bag_allocator_set(&allocator, sizeof(struct bag_epoch));
	if (ck_bag_init(&bag, b, CK_BAG_ALLOCATE_GEOMETRIC) == false) {
		fprintf(stderr, "Error: failed ck_bag_init().");
		exit(EXIT_FAILURE);
	}
	fprintf(stderr, "Configuration: %u entries, %zu bytes/block, %zu entries/block\n", writer_max, bag.info.bytes, bag.info.max);

	i = 1;
	/* Basic Test */
	ck_bag_put_spmc(&bag, (void *)(uintptr_t)i);
	ck_bag_remove_spmc(&bag, (void *)(uintptr_t)i);
	ck_bag_put_spmc(&bag, (void *)(uintptr_t)i);

	/* Sequential test */
	for (i = 1; i <= 10; i++)
		ck_bag_put_spmc(&bag, (void *)(uintptr_t)i);

	for (i = 1; i <= 10; i++)
		ck_bag_remove_spmc(&bag, (void *)(uintptr_t)i);

	for (i = 10; i > 0; i--)
		ck_bag_remove_spmc(&bag, (void *)(uintptr_t)i);

	for (i = 1; i <= 10; i++)
		ck_bag_put_spmc(&bag, (void *)(uintptr_t)i);

	ck_bag_iterator_init(&bag_it, &bag);
	while (ck_bag_next(&bag_it, &curr_ptr)) {
		curr = (uintptr_t)(curr_ptr);
		if (curr > (uintptr_t)i)
			fprintf(stderr, "ERROR: %ju != %u\n", (uintmax_t)curr, i);

		ck_bag_remove_spmc(&bag, curr_ptr);
	}

	/* Concurrent test */
	pthread_create(&writer, NULL, writer_thread, NULL);
	readers = malloc(sizeof(pthread_t) * NUM_READER_THREADS);
	for (i = 0; i < NUM_READER_THREADS; i++) {
		pthread_create(&readers[i], NULL, reader, NULL);
	}

	sleep(120);

	ck_pr_store_int(&leave, 1);
	for (i = 0; i < NUM_READER_THREADS; i++)
		pthread_join(readers[i], NULL);

	pthread_join(writer, NULL);
	fprintf(stderr, "Current entries: %u\n", ck_bag_count(&bag));
	ck_bag_destroy(&bag);
	return 0;
}