Example #1
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) {
		fprintf(stderr, "ERROR: Failed to allocate slots.\n");
		exit(EXIT_FAILURE);
	}
	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;
}
Example #2
0
static void *
test(void *c)
{
	struct context *context = c;
	struct entry *entry;
	ck_hp_fifo_entry_t *fifo_entry;
	ck_hp_record_t record;
	int i, j;

        if (aff_iterate(&a)) {
                perror("ERROR: Could not affine thread");
                exit(EXIT_FAILURE);
        }

	ck_hp_register(&fifo_hp, &record, malloc(sizeof(void *) * 2));
	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++) {
			fifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));
			entry = malloc(sizeof(struct entry));
			entry->tid = context->tid;
			ck_hp_fifo_enqueue_mpmc(&record, &fifo, fifo_entry, entry);

			fifo_entry = ck_hp_fifo_dequeue_mpmc(&record, &fifo, &entry);
			if (fifo_entry == NULL) {
				fprintf(stderr, "ERROR [%u] Queue should never be empty.\n", context->tid);
				exit(EXIT_FAILURE);
			}

			if (entry->tid < 0 || entry->tid >= nthr) {
				fprintf(stderr, "ERROR [%u] Incorrect value in entry.\n", entry->tid);
				exit(EXIT_FAILURE);
			}

			ck_hp_free(&record, &fifo_entry->hazard, fifo_entry, fifo_entry);
		}
	}

	ck_pr_inc_uint(&e_barrier);
	while (ck_pr_load_uint(&e_barrier) < (unsigned int)nthr);

	return (NULL);
}
Example #3
0
/* function for thread */
static void *
queue_50_50(void *elements)
{
        struct entry *entry;
        ck_hp_fifo_entry_t *fifo_entry;
	ck_hp_record_t *record;
	void *slots;
        unsigned long j, element_count = *(unsigned long *)elements;
	unsigned int seed;

	record = malloc(sizeof(ck_hp_record_t));
	assert(record);
	
	slots = malloc(CK_HP_FIFO_SLOTS_SIZE);
	assert(slots);
	
        /* different seed for each thread */
	seed = 1337; /*(unsigned int) pthread_self(); */

        /*
         * This subscribes the thread to the fifo_hp state using the thread-owned
         * record.
         * FIFO queue needs 2 hazard pointers.
         */
        ck_hp_register(&fifo_hp, record, slots);

	/* start barrier */
	ck_pr_inc_uint(&start_barrier);
	while (ck_pr_load_uint(&start_barrier) < thread_count + 1)
		ck_pr_stall();

	/* 50/50 enqueue-dequeue */
	for(j = 0; j < element_count; j++) {
		/* rand_r with thread local state should be thread safe */
		if( 50 < (1+(int) (100.0*common_rand_r(&seed)/(RAND_MAX+1.0)))) {
			/* This is the container for the enqueued data. */
        		fifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));

        		if (fifo_entry == NULL) {
        	        	exit(EXIT_FAILURE);
			}

        		/* This is the data. */
        		entry = malloc(sizeof(struct entry));
        		if (entry != NULL) {
        	        	entry->value = j;
			}

        	       /*
        	 	* Enqueue the value of the pointer entry into FIFO queue using the
        	 	* container fifo_entry.
        	 	*/
        		ck_hp_fifo_enqueue_mpmc(record, &fifo, fifo_entry, entry);
		} else {
			/*
        		 * ck_hp_fifo_dequeue_mpmc will return a pointer to the first unused node and store
        		 * the value of the first pointer in the FIFO queue in entry.
        		 */
  		      	fifo_entry = ck_hp_fifo_dequeue_mpmc(record, &fifo, &entry);
        		if (fifo_entry != NULL) {
               		 	/*
               		 	 * Safely reclaim memory associated with fifo_entry.
                		 * This inserts garbage into a local list. Once the list (plist) reaches
      			       	 * a length of 100, ck_hp_free will attempt to reclaim all references
                		 * to objects on the list.
        		       	 */
                		ck_hp_free(record, &fifo_entry->hazard, fifo_entry, fifo_entry);
        		}
		}
	}

	/* end barrier */
	ck_pr_inc_uint(&end_barrier);
	while (ck_pr_load_uint(&end_barrier) < thread_count + 1)
		ck_pr_stall();

       	return NULL;
}