Пример #1
0
void *test(void *data) {
	fprintf(stderr, "Starting test\n");
	//get the per-thread data
    thread_data_t *d = (thread_data_t *)data;

    //place the thread on the apropriate cpu
    set_cpu(the_cores[d->id]);
    int op_count = 10000;

    ssalloc_init();
    bst_init_local(d->id);

    /* Wait on barrier */
    barrier_cross(d->barrier);

	int i;
	bool_t added;

	for ( i = 1; i <= op_count; i++){

		added = bst_insert(i, root, d->id);
		// fprintf(stderr, "[%d] Added %d? %d\n", d->id, i, added==TRUE);
		if (added == TRUE) {
			d->num_insert++;
		}
	}

	// printf("Root right node: %d", root->right->key);
	
	for ( i = 1; i <= op_count; i++){

		node_t* found = bst_find(i, root, d->id);
		// printf("Contains %d? %d\n", i, found==FOUND);
		if (found != NULL) {
			d->num_search ++;
		} 
	}

	for ( i = 1; i <= op_count; i++){

		bool_t removed = bst_delete(i, root, d->id);
		// printf("Removed %d? %d\n", i, removed==TRUE);
		if (removed == TRUE) {
			d->num_remove ++;
		}
	}

	// for ( i = 1; i < 10; i++){

	// 	bool_t found = bst_contains(i);
	// 	printf("Contains %d? %d\n", i, found==FOUND);
	// }


	return NULL;
}
void *test(void *data)
{
    DDPRINT("starting test\n",NULL);
    //get the per-thread data
    thread_data_t *d = (thread_data_t *)data;
    //scale percentages of the various operations to the range 0..255
    //this saves us a floating point operation during the benchmark
    //e.g instead of random()%100 to determine the next operation we will do, we can simply do random()&256
    //this saves time on some platfroms
    uint32_t read_thresh = 256 * finds / 100;
    //uint32_t write_thresh = 256 * (finds + inserts) / 100;
    //place the thread on the apropriate cpu
    set_cpu(d->id);
    //initialize the custom memeory allocator for this thread (we do not use malloc due to concurrency bottleneck issues)
    ssalloc_init();
    // ssalloc_align();
    bst_init_local(d->id);
    //for fine-grain latency measurements, we need to get the lenght of a getticks() function call, which is also counted
    //by default when we do getticks(); //code... getticks(); PF_START and PF_STOP use this when fine grain measurements are enabled
    PF_CORRECTION;
    uint32_t rand_max;
    //seed the custom random number generator
    seeds = seed_rand();
    rand_max = max_key;
    uint32_t op;
    skey_t key;
    int i;
    int last = -1;

    DDPRINT("staring initial insert\n",NULL);
    DDPRINT("number of inserts: %u up to %u\n",d->num_add,rand_max);
    //before starting the test, we insert a number of elements in the data structure
    //we do this at each thread to avoid the situation where the entire data structure 
    //resides in the same memory node

    // int num_elem = 0;
    // if (num_threads == 1){
    //     num_elem = max_key/2;
    // } else{
    //     num_elem = max_key/4;
    // }
    // pthread_mutex_lock(d->init_lock);
    // fprintf(stderr, "Starting critical section %d\n", d->id);
    for (i=0;i<max_key/4;++i) {
        key = my_random(&seeds[0],&seeds[1],&seeds[2]) & rand_max;
 
        DDPRINT("key is %u\n",key);
        //we make sure the insert was effective (as opposed to just updating an existing entry)
        if (d->id < 2) {
        if (bst_add(key,root, d->id)!=TRUE) {
            i--;
        }   }
    }

    // fprintf(stderr, "Exiting critical section %d\n", d->id);
    // pthread_mutex_unlock(d->init_lock);
    DDPRINT("added initial data\n",NULL);

    bool_t res;
    /* Init of local data if necessary */
    ticks t1,t2;
    /* Wait on barrier */
    // fprintf(stderr, "Waiting on barrier; thread %d\n", d->id);
    barrier_cross(d->barrier);
    //start the test
    while (*running) {
        //generate a key (node that rand_max is expected to be a power of 2)
        key = my_random(&seeds[0],&seeds[1],&seeds[2]) & rand_max;
        //generate the operation
        op = my_random(&seeds[0],&seeds[1],&seeds[2]) & 0xff;
        if (op < read_thresh) {
            //do a find operation
            //PF_START and PF_STOP can be used to do latency measurements of the operation
            //to enable them, DO_TIMINGS must be defined at compile time, otherwise they do nothing
            //PF_START(2);
            bst_contains(key,root, d->id);
            //PF_STOP(2);
        } else if (last == -1) {
            //do a write operation
            if (bst_add(key,root, d->id)) {
                d->num_insert++;
                last=1;
            }
        } else {
            //do a delete operation
            if (bst_remove(key,root, d->id)) {
                d->num_remove++;
                last=-1;
            }
        }
        d->num_operations++;
        //memory barrier to ensure no unwanted reporderings are happening
        //MEM_BARRIER;
    }
    //summary of the fine grain measurements if enabled 
    PF_PRINT;
    return NULL;
}