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; }