Exemple #1
0
/*
 * [lyj] Disable the interpretation of "deleted" field.
 */
void fraser_insert(sl_intset_t *set, uint32_t v, bool lin)
{
    sl_node_t *NEW, *new_next, *pred, *succ, *succs[LEVELMAX], *preds[LEVELMAX];
    uint32_t i;
    uint32_t status;
   // uint32_t attempts = 0;
    NEW = sl_new_simple_node(v, get_rand_level(), lin);
retry:
    fraser_search(set, v, preds, succs);
    for (i = 0; i < NEW->toplevel; i++)
        NEW->nexts[i] = succs[i];
    /* Node is visible once inserted at lowest level */
    if (!ATOMIC_CAS_MB(&preds[0]->nexts[0], succs[0], NEW))
        goto retry;
    
//retry_HTM:
    status = _xbegin();
    if(status == _XBEGIN_STARTED)
    {
        for (i = 1; i < NEW->toplevel; i++) {
            if(preds[i]->nexts[i] == succs[i])
                preds[i]->nexts[i] = NEW;
            else
                _xabort(66);
        }
        _xend();
        return;
    }/*else
    {
        if ((status & _XABORT_EXPLICIT) && _XABORT_CODE(status) == 66) {
        }
        else if (++attempts < MAX_ATTEMPT_NUM) {
            goto retry_HTM;
        }
    }*/
    
    for (i = 1; i < NEW->toplevel; i++) {
        while (1) {
            pred = preds[i];
            succ = succs[i];
            /* Update the forward pointer if it is stale */
            new_next = NEW->nexts[i];
            if ((new_next != succ) &&
                (!ATOMIC_CAS_MB(&NEW->nexts[i], unset_mark((uint32_t)new_next), succ)))
                break;
            /* Give up if pointer is marked */
            /* We retry the search if the CAS fails */
            if (ATOMIC_CAS_MB(&pred->nexts[i], succ, NEW))
                break;
            fraser_search(set, v, preds, succs);
        }
    }
}
Exemple #2
0
inline int mark_node_ptrs(sl_node_t *n)
{
    sl_node_t *n_next;
    
    uint32_t status;
    //uint32_t attempts = 0;
    uint32_t i = n->toplevel - 1;
//retry:
    status = _xbegin();
    if(status == _XBEGIN_STARTED)
    {
        while ( i > 0 )
        {
            if(!is_marked((uint32_t)n->nexts[i]))
                n->nexts[i] = (sl_node_t*)set_mark((uint32_t)n->nexts[i]);
            i--;
        }
        if (is_marked((uint32_t)n->nexts[0]))
        {
            _xend();
            return 0;
        }else
        {
            n->nexts[0] = (sl_node_t*)set_mark((uint32_t)n->nexts[0]);
            _xend();
            return 1;
        }
    }/*else{
        if (++attempts < MAX_ATTEMPT_NUM) {
            goto retry;
        }
    }*/
        
    for (int i=n->toplevel-1; i>0; i--) {
        do {
            n_next = n->nexts[i];
            if (is_marked((uint32_t)n_next))
                break;
            if (ATOMIC_CAS_MB(&n->nexts[i], n_next, (sl_node_t*)set_mark((uint32_t)n_next)))
                break;
        } while (true);
    }
    do {
        n_next = n->nexts[0];
        if (is_marked((uint32_t)n_next))
            return 0;
        if (ATOMIC_CAS_MB(&n->nexts[0], n_next, (sl_node_t*)set_mark((uint32_t)n_next)))
            return 1;
    } while (true);
}
Exemple #3
0
// Fraser's SkipList Algorithm
inline void fraser_search(sl_intset_t *set, uint32_t val, sl_node_t **left_list, sl_node_t **right_list)
{
    int i;
    sl_node_t *left, *left_next, *right, *right_next;
retry:
    left = set->head;
    for (i = LEVELMAX - 1; i >= 0; i--) {
        left_next = left->nexts[i];
        if (is_marked((uint32_t)left_next))
            goto retry;
        /* Find unmarked node pair at this level */
        for (right = left_next; ; right = right_next) {
            /* Skip a sequence of marked nodes */
            while(1) {
                right_next = right->nexts[i];
                if (!is_marked((uint32_t)right_next))
                    break;
                right = (sl_node_t*)unset_mark((uint32_t)right_next);
            }
            if (right->val >= val)
                break;
            left = right;
            left_next = right_next;
        }
        
        /* Ensure left and right nodes are adjacent */
        if ((left_next != right) &&
            (!ATOMIC_CAS_MB(&left->nexts[i], left_next, right)))
            goto retry;
        if (left_list != NULL)
            left_list[i] = left;
        if (right_list != NULL)
            right_list[i] = right;
    }
}
Exemple #4
0
/*
 * harris_find deletes a node with the given value val (if the value is present)
 * or does nothing (if the value is already present).
 * The deletion is logical and consists of setting the node mark bit to 1.
 */
int harris_delete(intset_t *set, val_t val) {
    node_t *right_node, *right_node_next, *left_node;
    left_node = set->head;

    do {
        right_node = harris_search(set, val, &left_node);
        if (right_node->val != val)
            return 0;
        right_node_next = right_node->next;
        if (!is_marked_ref((long) right_node_next))
            if (ATOMIC_CAS_MB(&right_node->next,
                              right_node_next,
                              get_marked_ref((long) right_node_next)))
                break;
    } while(1);
    if (!ATOMIC_CAS_MB(&left_node->next, right_node, right_node_next))
        right_node = harris_search(set, right_node->val, &left_node);
    return 1;
}
Exemple #5
0
void mark_node_ptrs(sl_node_t *n) {
  int i;
  sl_node_t *n_next;
	
  for (i=n->toplevel-1; i>=0; i--) {
    do {
      n_next = n->next[i];
      if (is_marked((uintptr_t)n_next))
        break;
    } while (!ATOMIC_CAS_MB(&n->next[i], n_next, set_mark((uintptr_t)n_next)));
  }
}
Exemple #6
0
int		
fraser_search(sl_intset_t *set, skey_t key, sl_node_t **left_list, sl_node_t **right_list)
{
  int i;
  sl_node_t *left, *left_next, *right = NULL, *right_next;

 retry:
  PARSE_TRY();

  left = set->head;
  for (i = levelmax - 1; i >= 0; i--)
    {
      left_next = left->next[i];
      if ((is_marked((uintptr_t)left_next)))
	{
	  goto retry;
	}
      /* Find unmarked node pair at this level */
      for (right = left_next; ; right = right_next)
	{
	  /* Skip a sequence of marked nodes */
	  right_next = right->next[i];
	  while ((is_marked((uintptr_t)right_next)))
	    {
	      right = (sl_node_t*)unset_mark((uintptr_t)right_next);
	      right_next = right->next[i];
	    }

	  if (right->key >= key)
	    {
	      break;
	    }
	  left = right; 
	  left_next = right_next;
	}
      /* Ensure left and right nodes are adjacent */
      if ((left_next != right) && (!ATOMIC_CAS_MB(&left->next[i], left_next, right)))
	{
	  goto retry;
	}

      if (left_list != NULL)
      	{
	  left_list[i] = left;
      	}
      if (right_list != NULL)
      	{
	  right_list[i] = right;
	}
    }
  return (right->key == key);
}
Exemple #7
0
/*
 * harris_find inserts a new node with the given value val in the list
 * (if the value was absent) or does nothing (if the value is already present).
 */
int harris_insert(intset_t *set, val_t val) {
    node_t *newnode, *right_node, *left_node;
    left_node = set->head;

    do {
        right_node = harris_search(set, val, &left_node);
        if (right_node->val == val)
            return 0;
        newnode = new_node(val, right_node, 0);
        /* mem-bar between node creation and insertion */
        AO_nop_full();
        if (ATOMIC_CAS_MB(&left_node->next, right_node, newnode))
            return 1;
    } while(1);
}
Exemple #8
0
void fraser_search(sl_intset_t *set, val_t val, sl_node_t **left_list, sl_node_t **right_list) {
  int i;
  sl_node_t *left, *left_next, *right, *right_next;

#ifdef DEBUG
  printf("++> fraser_search\n");
  IO_FLUSH;
#endif

retry:
  left = set->head;
  for (i = levelmax - 1; i >= 0; i--) {
    left_next = left->next[i];
    if (is_marked((uintptr_t)left_next))
      goto retry;
    /* Find unmarked node pair at this level */
    for (right = left_next; ; right = right_next) {
      /* Skip a sequence of marked nodes */
      while(1) {
        right_next = right->next[i];
        if (!is_marked((uintptr_t)right_next))
          break;
        right = (sl_node_t*)unset_mark((uintptr_t)right_next);
      }
      if (right->val >= val)
        break;
      left = right; 
      left_next = right_next;
    }
    /* Ensure left and right nodes are adjacent */
    if ((left_next != right) && 
        (!ATOMIC_CAS_MB(&left->next[i], left_next, right)))
      goto retry;
    if (left_list != NULL)
      left_list[i] = left;
    if (right_list != NULL)	
      right_list[i] = right;
  }

#ifdef DEBUG
  printf("++> fraser_search ends\n");
  IO_FLUSH;
#endif
}
Exemple #9
0
/*
 * harris_search looks for value val, it
 *  - returns right_node owning val (if present) or its immediately higher
 *    value present in the list (otherwise) and
 *  - sets the left_node to the node owning the value immediately lower than val.
 * Encountered nodes that are marked as logically deleted are physically removed
 * from the list, yet not garbage collected.
 */
node_t *harris_search(intset_t *set, val_t val, node_t **left_node) {
    node_t *left_node_next, *right_node;
    left_node_next = set->head;

search_again:
    do {
        node_t *t = set->head;
        node_t *t_next = set->head->next;

        /* Find left_node and right_node */
        do {
            if (!is_marked_ref((long) t_next)) {
                (*left_node) = t;
                left_node_next = t_next;
            }
            t = (node_t *) get_unmarked_ref((long) t_next);
            if (!t->next) break;
            t_next = t->next;
        } while (is_marked_ref((long) t_next) || (t->val < val));
        right_node = t;

        /* Check that nodes are adjacent */
        if (left_node_next == right_node) {
            if (right_node->next && is_marked_ref((long) right_node->next))
                goto search_again;
            else return right_node;
        }

        /* Remove one or more marked nodes */
        if (ATOMIC_CAS_MB(&(*left_node)->next,
                          left_node_next,
                          right_node)) {
            if (right_node->next && is_marked_ref((long) right_node->next))
                goto search_again;
            else return right_node;
        }

    } while (1);
}
Exemple #10
0
inline int
mark_node_ptrs(sl_node_t *n)
{
  int i, cas = 0;
  sl_node_t* n_next;
	
  for (i = n->toplevel - 1; i >= 0; i--)
    {
      do
      	{
      	  n_next = n->next[i];
      	  if (is_marked((uintptr_t)n_next))
      	    {
	      cas = 0;
      	      break;
      	    }
	  cas = ATOMIC_CAS_MB(&n->next[i], GET_UNMARKED(n_next), set_mark((uintptr_t)n_next));
      	} 
      while (!cas);
    }

  return (cas);	/* if I was the one that marked lvl 0 */
}
Exemple #11
0
void* sssp(void *data) {
  thread_data_t *d = (thread_data_t *)data;

  /* Create transaction */
  set_cpu(the_cores[d->id]);
  /* Wait on barrier */
  ssalloc_init();
  PF_CORRECTION;

  seeds = seed_rand();

#ifdef PIN
  int id = d->id;
  // int cpu = 40*(id/40) + 4*(id%10) + (id%40)/10;
  int cpu = 4*(id%20) + id/20; 
  // printf("Pinning %d to %d\n",id,cpu);
  pin(pthread_self(), cpu);
  //  pin(pthread_self(), id);
#endif

 #ifdef PAPI
    if (PAPI_OK != PAPI_start_counters(g_events, G_EVENT_COUNT))
  {
    printf("Problem starting counters 1.");
  }
 #endif


  barrier_cross(d->barrier);

  // Begin SSSP

  int fail = 0;
  // int radius = 0;
  while (1) {
    val_t node;
    slkey_t dist_node;
  //   print_skiplist(d->set);
    while (1) { 
     if (d->sl) {
       if (spray_delete_min_key(d->set, &dist_node, &node, d)) break; // keep trying until get a node
     } else if (d->pq) {
       if (lotan_shavit_delete_min_key(d->set, &dist_node, &node, d)) break;
     } else if (d->lin) {
       node = (val_t) deletemin_key(d->linden_set, &dist_node, d); break;
     } else {
       printf("error: no queue selected\n");
       exit(1); // TODO: grace
     }
     if (dist_node == -1) { // flag that list is empty
       break;
     }
     dist_node = 0;
    }
    if (dist_node == -1) { // list is empty; TODO make sure threads don't quit early
      fail++;
      if (fail > 20*d->nb_threads) { // TODO: really need a better break condition...
        break;
      }
      continue;
    }
    fail = 0;
    if (dist_node != nodes[node].dist) continue; // dead node
    nodes[node].times_processed++;

    int i;
    for (i = 0;i < nodes[node].deg;i++) {
      int v = nodes[node].adj[i];
      int w = nodes[node].weights[i];
      slkey_t dist_v = nodes[v].dist;
  //  printf("v=%d dist_v=%d\n", v, dist_v);
      if (dist_v == -1 || dist_node + w < dist_v) { // found better path to v
  //       printf("attempting cas...\n");
  //       printf("nodes[v].dist=%d dist_v=%d dist_node=%d\n", nodes[v].dist, dist_v, dist_node);
        int res = ATOMIC_CAS_MB(&nodes[v].dist, dist_v, dist_node+w);
  //       printf("%d nodes[%d].dist=%d\n", res, v, nodes[v].dist);
        if (res) {
          if (d->pq || d->sl) {
            sl_add_val(d->set, dist_node+w, v, TRANSACTIONAL); // add to queue only if CAS is successful
          } else if (d->lin) {
            insert(d->linden_set, dist_node+w, v);
          }
          d->nb_add++;
  //         if (dist_node+1 > radius) {
  //           radius = dist_node+1;
  //           printf("radius %d\n", radius);
  //         }
        }
      } 
    }
  }

  // End SSSP
  
#ifdef PAPI
  if (PAPI_OK != PAPI_read_counters(g_values[d->id], G_EVENT_COUNT))
  {
    printf("Problem reading counters 2.");
  }
#endif

  PF_PRINT;

  return NULL;
}