Beispiel #1
0
int main(int argc, char **argv)
{
	int values[] = { -5, 42, 36, 24, };
	struct cds_lfq_queue_rcu myqueue;	/* Queue */
	unsigned int i;
	int ret = 0;

	/*
	 * Each thread need using RCU read-side need to be explicitly
	 * registered.
	 */
	urcu_memb_register_thread();

	cds_lfq_init_rcu(&myqueue, urcu_memb_call_rcu);

	/*
	 * Enqueue nodes.
	 */
	for (i = 0; i < CAA_ARRAY_SIZE(values); i++) {
		struct mynode *node;

		node = malloc(sizeof(*node));
		if (!node) {
			ret = -1;
			goto end;
		}

		cds_lfq_node_init_rcu(&node->node);
		node->value = values[i];
		/*
		 * Both enqueue and dequeue need to be called within RCU
		 * read-side critical section.
		 */
		urcu_memb_read_lock();
		cds_lfq_enqueue_rcu(&myqueue, &node->node);
		urcu_memb_read_unlock();
	}

end:
	urcu_memb_unregister_thread();
	return ret;
}
Beispiel #2
0
int main(int argc, char **argv)
{
    int err;
    pthread_t *tid_enqueuer, *tid_dequeuer;
    void *tret;
    unsigned long long *count_enqueuer, *count_dequeuer;
    unsigned long long tot_enqueues = 0, tot_dequeues = 0;
    unsigned long long tot_successful_enqueues = 0,
                       tot_successful_dequeues = 0;
    unsigned long long end_dequeues = 0;
    int i, a;

    if (argc < 4) {
        show_usage(argc, argv);
        return -1;
    }

    err = sscanf(argv[1], "%u", &nr_dequeuers);
    if (err != 1) {
        show_usage(argc, argv);
        return -1;
    }

    err = sscanf(argv[2], "%u", &nr_enqueuers);
    if (err != 1) {
        show_usage(argc, argv);
        return -1;
    }

    err = sscanf(argv[3], "%lu", &duration);
    if (err != 1) {
        show_usage(argc, argv);
        return -1;
    }

    for (i = 4; i < argc; i++) {
        if (argv[i][0] != '-')
            continue;
        switch (argv[i][1]) {
        case 'a':
            if (argc < i + 2) {
                show_usage(argc, argv);
                return -1;
            }
            a = atoi(argv[++i]);
            cpu_affinities[next_aff++] = a;
            use_affinity = 1;
            printf_verbose("Adding CPU %d affinity\n", a);
            break;
        case 'c':
            if (argc < i + 2) {
                show_usage(argc, argv);
                return -1;
            }
            rduration = atol(argv[++i]);
            break;
        case 'd':
            if (argc < i + 2) {
                show_usage(argc, argv);
                return -1;
            }
            wdelay = atol(argv[++i]);
            break;
        case 'v':
            verbose_mode = 1;
            break;
        }
    }

    printf_verbose("running test for %lu seconds, %u enqueuers, "
                   "%u dequeuers.\n",
                   duration, nr_enqueuers, nr_dequeuers);
    printf_verbose("Writer delay : %lu loops.\n", rduration);
    printf_verbose("Reader duration : %lu loops.\n", wdelay);
    printf_verbose("thread %-6s, tid %lu\n",
                   "main", urcu_get_thread_id());

    tid_enqueuer = calloc(nr_enqueuers, sizeof(*tid_enqueuer));
    tid_dequeuer = calloc(nr_dequeuers, sizeof(*tid_dequeuer));
    count_enqueuer = calloc(nr_enqueuers, 2 * sizeof(*count_enqueuer));
    count_dequeuer = calloc(nr_dequeuers, 2 * sizeof(*count_dequeuer));
    cds_lfq_init_rcu(&q, call_rcu);
    err = create_all_cpu_call_rcu_data(0);
    if (err) {
        printf("Per-CPU call_rcu() worker threads unavailable. Using default global worker thread.\n");
    }

    next_aff = 0;

    for (i = 0; i < nr_enqueuers; i++) {
        err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer,
                             &count_enqueuer[2 * i]);
        if (err != 0)
            exit(1);
    }
    for (i = 0; i < nr_dequeuers; i++) {
        err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer,
                             &count_dequeuer[2 * i]);
        if (err != 0)
            exit(1);
    }

    cmm_smp_mb();

    test_go = 1;

    for (i = 0; i < duration; i++) {
        sleep(1);
        if (verbose_mode) {
            fwrite(".", sizeof(char), 1, stdout);
            fflush(stdout);
        }
    }

    test_stop = 1;

    for (i = 0; i < nr_enqueuers; i++) {
        err = pthread_join(tid_enqueuer[i], &tret);
        if (err != 0)
            exit(1);
        tot_enqueues += count_enqueuer[2 * i];
        tot_successful_enqueues += count_enqueuer[2 * i + 1];
    }
    for (i = 0; i < nr_dequeuers; i++) {
        err = pthread_join(tid_dequeuer[i], &tret);
        if (err != 0)
            exit(1);
        tot_dequeues += count_dequeuer[2 * i];
        tot_successful_dequeues += count_dequeuer[2 * i + 1];
    }

    test_end(&q, &end_dequeues);
    err = cds_lfq_destroy_rcu(&q);
    assert(!err);

    printf_verbose("total number of enqueues : %llu, dequeues %llu\n",
                   tot_enqueues, tot_dequeues);
    printf_verbose("total number of successful enqueues : %llu, "
                   "successful dequeues %llu\n",
                   tot_successful_enqueues, tot_successful_dequeues);
    printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu "
           "nr_dequeuers %3u "
           "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu "
           "successful enqueues %12llu successful dequeues %12llu "
           "end_dequeues %llu nr_ops %12llu\n",
           argv[0], duration, nr_enqueuers, wdelay,
           nr_dequeuers, rduration, tot_enqueues, tot_dequeues,
           tot_successful_enqueues,
           tot_successful_dequeues, end_dequeues,
           tot_enqueues + tot_dequeues);
    if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues)
        printf("WARNING! Discrepancy between nr succ. enqueues %llu vs "
               "succ. dequeues + end dequeues %llu.\n",
               tot_successful_enqueues,
               tot_successful_dequeues + end_dequeues);

    free_all_cpu_call_rcu_data();
    free(count_enqueuer);
    free(count_dequeuer);
    free(tid_enqueuer);
    free(tid_dequeuer);
    return 0;
}