bag_elem_t avl_contains(const avl_node_t *root, bag_elem_t elem, int (*cmp)(bag_elem_t, bag_elem_t)) { if (! root) return NULL; else if ((*cmp)(elem, root->elem) < 0) return avl_contains(root->left, elem, cmp); else if ((*cmp)(elem, root->elem) > 0) return avl_contains(root->right, elem, cmp); else /* ((*cmp)(elem, root->elem) == 0) */ return root->elem; }
void *test(void *data) { int unext, last = -1; val_t val = 0; int result; int id; ulong *tloc; #ifdef BIAS_RANGE val_t increase; #endif thread_data_t *d = (thread_data_t *)data; id = d->id; tloc = d->set->nb_committed; #ifdef BIAS_RANGE increase = d->range; #endif /* Create transaction */ TM_THREAD_ENTER(); /* Wait on barrier */ barrier_cross(d->barrier); /* Is the first op an update? */ unext = (rand_range_re(&d->seed, 100) - 1 < d->update); #ifdef ICC while (stop == 0) { #else while (AO_load_full(&stop) == 0) { #endif /* ICC */ if (unext) { // update if (last < 0) { // add val = rand_range_re(&d->seed, d->range); #ifdef BIAS_RANGE if(rand_range_re(&d->seed, 1000) < 50) { increase += rand_range_re(&d->seed, 10); if(increase > d->range * 20) { increase = d->range; } val = increase; } #endif if ((result = avl_add(d->set, val, TRANSACTIONAL, id)) > 0) { d->nb_added++; if(result > 1) { d->nb_modifications++; } last = val; } d->nb_trans++; tloc[id]++; d->nb_add++; } else { // remove if (d->alternate) { // alternate mode (default) #ifdef TINY10B if ((result = avl_remove(d->set, last, TRANSACTIONAL, id)) > 0) { #else if ((result = avl_remove(d->set, last, TRANSACTIONAL, 0)) > 0) { #endif d->nb_removed++; #ifdef REMOVE_LATER finish_removal(d->set, id); #endif if(result > 1) { d->nb_modifications++; } } last = -1; } else { /* Random computation only in non-alternated cases */ val = rand_range_re(&d->seed, d->range); /* Remove one random value */ #ifdef BIAS_RANGE if(rand_range_re(&d->seed, 1000) < 300) { //val = d->range + rand_range_re(&d->seed, increase - d->range); val = increase - rand_range_re(&d->seed, 10); } #endif #ifdef TINY10B if ((result = avl_remove(d->set, val, TRANSACTIONAL, id)) > 0) { #else if ((result = avl_remove(d->set, val, TRANSACTIONAL, 0)) > 0) { #endif d->nb_removed++; #ifdef REMOVE_LATER finish_removal(d->set, id); #endif if(result > 1) { d->nb_modifications++; } /* Repeat until successful, to avoid size variations */ last = -1; } } d->nb_trans++; tloc[id]++; d->nb_remove++; } } else { // read if (d->alternate) { if (d->update == 0) { if (last < 0) { val = d->first; last = val; } else { // last >= 0 val = rand_range_re(&d->seed, d->range); last = -1; } } else { // update != 0 if (last < 0) { val = rand_range_re(&d->seed, d->range); //last = val; } else { val = last; } } } else val = rand_range_re(&d->seed, d->range); #ifdef BIAS_RANGE if(rand_range_re(&d->seed, 1000) < 100) { val = increase; } #endif if (avl_contains(d->set, val, TRANSACTIONAL, id)) d->nb_found++; d->nb_trans++; tloc[id]++; d->nb_contains++; } /* Is the next op an update? */ if (d->effective) { // a failed remove/add is a read-only tx unext = ((100 * (d->nb_added + d->nb_removed)) < (d->update * (d->nb_add + d->nb_remove + d->nb_contains))); } else { // remove/add (even failed) is considered as an update unext = (rand_range_re(&d->seed, 100) - 1 < d->update); } #ifdef ICC } #else } #endif /* ICC */ /* Free transaction */ TM_THREAD_EXIT(); return NULL; } void *test_maintenance(void *data) { #ifdef TINY10B int i; free_list_item **t_list_items; #endif maintenance_thread_data_t *d = (maintenance_thread_data_t *)data; #ifdef TINY10B t_list_items = (free_list_item **)malloc(d->nb_threads * sizeof(free_list_item *)); for(i = 0; i < d->nb_threads; i++) { t_list_items[i] = d->set->t_free_list[i]; } #endif /* Create transaction */ TM_THREAD_ENTER(); /* Wait on barrier */ barrier_cross(d->barrier); /* Is the first op an update? */ //unext = (rand_range_re(&d->seed, 100) - 1 < d->update); #ifdef ICC while (stop == 0) { #else while (AO_load_full(&stop) == 0) { #endif /* ICC */ #ifdef TINY10B do_maintenance_thread(d->set, d->id, d->nb_maint); #endif #ifdef ICC } #else } #endif /* ICC */ /* Free transaction */ TM_THREAD_EXIT(); return NULL; } void catcher(int sig) { printf("CAUGHT SIGNAL %d\n", sig); }
void *test2(void *data) { int val, newval, last, flag = 1; int id; ulong *tloc; thread_data_t *d = (thread_data_t *)data; id = d->id; tloc = d->set->nb_committed; /* Create transaction */ TM_THREAD_ENTER(); /* Wait on barrier */ barrier_cross(d->barrier); last = 0; // to avoid warning while (stop == 0) { val = rand_range_re(&d->seed, 100) - 1; /* added for HashTables */ if (val < d->update) { if (val >= d->move) { /* update without move */ if (flag) { /* Add random value */ val = (rand_r(&d->seed) % d->range) + 1; if (avl_add(d->set, val, TRANSACTIONAL, id)) { d->nb_added++; last = val; flag = 0; } d->nb_trans++; tloc[id]++; d->nb_add++; } else { if (d->alternate) { /* Remove last value */ if (avl_remove(d->set, last, TRANSACTIONAL, id)) d->nb_removed++; d->nb_trans++; tloc[id]++; d->nb_remove++; flag = 1; } else { /* Random computation only in non-alternated cases */ newval = rand_range_re(&d->seed, d->range); if (avl_remove(d->set, newval, TRANSACTIONAL, id)) { d->nb_removed++; /* Repeat until successful, to avoid size variations */ flag = 1; } d->nb_trans++; tloc[id]++; d->nb_remove++; } } } else { /* move */ val = rand_range_re(&d->seed, d->range); if (avl_move(d->set, last, val, TRANSACTIONAL, id)) { d->nb_moved++; last = val; } d->nb_trans++; tloc[id]++; d->nb_move++; } } else { if (val >= d->update + d->snapshot) { /* read-only without snapshot */ /* Look for random value */ val = rand_range_re(&d->seed, d->range); if (avl_contains(d->set, val, TRANSACTIONAL, id)) d->nb_found++; d->nb_trans++; tloc[id]++; d->nb_contains++; } else { /* snapshot */ if (avl_snapshot(d->set, TRANSACTIONAL, id)) d->nb_snapshoted++; d->nb_trans++; tloc[id]++; d->nb_snapshot++; } } } /* Free transaction */ TM_THREAD_EXIT(); return NULL; }
bag_elem_t bag_contains(bag_t *bag, bag_elem_t elem) { return avl_contains(bag->root, elem, bag->cmp); }
void *test(void *data) { int val2, numtx, r, last = -1; val_t val = 0; int unext, mnext, cnext; int id; ulong *tloc; thread_data_t *d = (thread_data_t *)data; id = d->id; tloc = d->set->nb_committed; /* Create transaction */ TM_THREAD_ENTER(); /* Wait on barrier */ barrier_cross(d->barrier); /* Is the first op an update, a move? */ r = rand_range_re(&d->seed, 100) - 1; unext = (r < d->update); mnext = (r < d->move); cnext = (r >= d->update + d->snapshot); #ifdef ICC while (stop == 0) { #else while (AO_load_full(&stop) == 0) { #endif /* ICC */ if (unext) { // update if (mnext) { // move if (last == -1) val = rand_range_re(&d->seed, d->range); else val = last; val2 = rand_range_re(&d->seed, d->range); if (avl_move(d->set, val, val2, TRANSACTIONAL, id)) { d->nb_moved++; last = -1; } d->nb_trans++; tloc[id]++; d->nb_move++; } else if (last < 0) { // add val = rand_range_re(&d->seed, d->range); if (avl_add(d->set, val, TRANSACTIONAL, id)) { d->nb_added++; last = val; } d->nb_trans++; tloc[id]++; d->nb_add++; } else { // remove if (d->alternate) { // alternate mode if (avl_remove(d->set, last, TRANSACTIONAL, id)) { d->nb_removed++; #ifdef REMOVE_LATER finish_removal(d->set, id); #endif last = -1; } } else { /* Random computation only in non-alternated cases */ val = rand_range_re(&d->seed, d->range); /* Remove one random value */ if (avl_remove(d->set, val, TRANSACTIONAL, id)) { d->nb_removed++; /* Repeat until successful, to avoid size variations */ last = -1; } } d->nb_trans++; tloc[id]++; d->nb_remove++; } } else { // reads if (cnext) { // contains (no snapshot) if (d->alternate) { if (d->update == 0) { if (last < 0) { val = d->first; last = val; } else { // last >= 0 val = rand_range_re(&d->seed, d->range); last = -1; } } else { // update != 0 if (last < 0) { val = rand_range_re(&d->seed, d->range); //last = val; } else { val = last; } } } else val = rand_range_re(&d->seed, d->range); if (avl_contains(d->set, val, TRANSACTIONAL, id)) d->nb_found++; d->nb_trans++; tloc[id]++; d->nb_contains++; } else { // snapshot if (avl_snapshot(d->set, TRANSACTIONAL, id)) d->nb_snapshoted++; d->nb_trans++; tloc[id]++; d->nb_snapshot++; } } /* Is the next op an update, a move, a contains? */ if (d->effective) { // a failed remove/add is a read-only tx numtx = d->nb_contains + d->nb_add + d->nb_remove + d->nb_move + d->nb_snapshot; unext = ((100.0 * (d->nb_added + d->nb_removed + d->nb_moved)) < (d->update * numtx)); mnext = ((100.0 * d->nb_moved) < (d->move * numtx)); cnext = !((100.0 * d->nb_snapshoted) < (d->snapshot * numtx)); } else { // remove/add (even failed) is considered as an update r = rand_range_re(&d->seed, 100) - 1; unext = (r < d->update); mnext = (r < d->move); cnext = (r >= d->update + d->snapshot); } #ifdef ICC } #else } #endif /* ICC */ /* Free transaction */ TM_THREAD_EXIT(); return NULL; }