Esempio n. 1
0
sval_t
fraser_remove(sl_intset_t *set, skey_t key)
{
  UPDATE_TRY();

  sl_node_t* succs[FRASER_MAX_MAX_LEVEL];
  sval_t result = 0;

  PARSE_START_TS(2);
  int found = fraser_search_no_cleanup_succs(set, key, succs);
  PARSE_END_TS(2, lat_parsing_rem++);

  if (!found)
    {
      return false;
    }

  sl_node_t* node_del = succs[0];
  int my_delete = mark_node_ptrs(node_del);

  if (my_delete)
    {
      result = node_del->val;
      fraser_search(set, key, NULL, NULL);
#if GC == 1
      ssmem_free(alloc, (void*) succs[0]);
#endif
    }
  return result;
}
Esempio n. 2
0
sval_t
optimistic_find(sl_intset_t *set, skey_t key)
{
    PARSE_TRY();
    PARSE_START_TS(0);
    sval_t val = 0;
    sl_node_t* succ = NULL;
    sl_node_t* pred = set->head;
    int lvl;
    for (lvl = levelmax - 1; lvl >= 0; lvl--)
    {
        succ = pred->next[lvl];
        while (succ->key < key)
        {
            pred = succ;
            succ = succ->next[lvl];
        }

        if (succ->key == key)	/* at any search level */
        {
            val = succ->val;
            break;
        }
    }

    PARSE_END_TS(0, lat_parsing_get++);
    return val;
}
Esempio n. 3
0
skey_t
alistarh_spray(sl_intset_t *set)
{
    sl_node_t *next, *node;
    int i, level;

retry:
    UPDATE_TRY();
    PARSE_START_TS(3);
    node = set->head;
    next = NULL;
    for(level = starting_height; level>=0; level-=ALISTARH_LEVELS_TO_DESCEND)
    {
        i = (int)rand_range(max_jump_length);
        for (; i>0; i--)
        {
            next = node->next[level];
            if (next==NULL || next->next[0]==NULL)
                break;
            node = next;
        }
    }
    PARSE_END_TS(3, lat_parsing_deleteMin++);
    if (unlikely(node == set->head))
        goto retry;

    if (unlikely(node->val == KEY_MIN+1))
        goto retry;

    return node->key;
}
Esempio n. 4
0
sval_t
fraser_find(sl_intset_t *set, skey_t key)
{
  sval_t result = 0;
  PARSE_START_TS(0);
  sl_node_t* left = fraser_left_search(set, key);
  PARSE_END_TS(0, lat_parsing_get++);

  if (left->key == key)
    {
      result = left->val;
    }
  return result;
}
Esempio n. 5
0
/*
 * Function optimistic_find corresponds to the contains method of the original 
 * paper. In contrast with the original version, it allocates and frees the 
 * memory at right places to avoid the use of a stop-the-world garbage 
 * collector. 
 */
sval_t
optimistic_find(sl_intset_t *set, skey_t key)
{ 
  sval_t result = 0;

  PARSE_START_TS(0);
  sl_node_t* nd = optimistic_left_search(set, key);
  PARSE_END_TS(0, lat_parsing_get++);

  if (nd != NULL && !nd->marked && nd->fullylinked)
    {
      result = nd->val;
    }
  return result;
}
Esempio n. 6
0
sval_t
prioritySL_deleteMin(sl_intset_t *set)
{
  sval_t result = 0;
  sl_node_t *node;
  PARSE_START_TS(4);
  node = GET_UNMARKED(set->head->next[0]);
  while(node->next[0]!=NULL)
  {
    if (!IS_MARKED(node->next[node->toplevel-1]))
    {
      int my_delete = mark_node_ptrs(node);
      if (my_delete)
      {
        result = node->val;
        fraser_search(set, node->key, NULL, NULL);
        break;
      }
    }
    node = GET_UNMARKED(node->next[0]);
  }
  PARSE_END_TS(4, lat_parsing_cleaner++);
  return result;
}
Esempio n. 7
0
/*
 * Function optimistic_delete is similar to the method remove of the paper.
 * Here we avoid the fast search parameter as the comparison is faster in C 
 * than calling the Java compareTo method of the Comparable interface 
 * (cf. p132 of SIROCCO'07 proceedings).
 */
sval_t
optimistic_delete(sl_intset_t *set, skey_t key)
{
  sl_node_t *succs[HERLIHY_MAX_MAX_LEVEL], *preds[HERLIHY_MAX_MAX_LEVEL];
  sl_node_t *node_todel, *prev_pred; 
  sl_node_t *pred, *succ;
  int is_marked, toplevel, highest_locked, i, valid, found;	
  unsigned int backoff;

  node_todel = NULL;
  is_marked = 0;
  toplevel = -1;
  backoff = 1;
	
  PARSE_START_TS(2);
  while(1)
    {
      UPDATE_TRY();
      found = optimistic_search(set, key, preds, succs, 1);
      PARSE_END_TS(2, lat_parsing_rem);

      /* If not marked and ok to delete, then mark it */
      if (is_marked || (found != -1 && ok_to_delete(succs[found], found)))
	{	
	  GL_LOCK(set->lock); /* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
	  if (!is_marked)
	    {
	      node_todel = succs[found];

	      LOCK(ND_GET_LOCK(node_todel));
	      toplevel = node_todel->toplevel;
	      /* Unless it has been marked meanwhile */

	      if (node_todel->marked)
		{
		  GL_UNLOCK(set->lock);
		  UNLOCK(ND_GET_LOCK(node_todel));
		  PARSE_END_INC(lat_parsing_rem);
		  return 0;
		}

	      node_todel->marked = 1;
	      is_marked = 1;
	    }

	  /* Physical deletion */
	  highest_locked = -1;
	  prev_pred = NULL;
	  valid = 1;
	  for (i = 0; valid && (i < toplevel); i++)
	    {
	      pred = preds[i];
	      succ = succs[i];
	      if (pred != prev_pred)
		{
		  LOCK(ND_GET_LOCK(pred));
		  highest_locked = i;
		  prev_pred = pred;
		}

	      valid = (!pred->marked && ((volatile sl_node_t*) pred->next[i] == 
					 (volatile sl_node_t*) succ));
	    }

	  if (!valid)
	    {	
	      unlock_levels(set, preds, highest_locked);
	      if (backoff > 5000) 
		{
		  nop_rep(backoff & MAX_BACKOFF);
		}
	      backoff <<= 1;
	      continue;
	    }
			
	  for (i = (toplevel-1); i >= 0; i--)
	    {
	      preds[i]->next[i] = node_todel->next[i];
	    }

	  sval_t val = node_todel->val;
#if GC == 1
	  ssmem_free(alloc, (void*) node_todel);
#endif

	  UNLOCK(ND_GET_LOCK(node_todel));
	  unlock_levels(set, preds, highest_locked);

	  PARSE_END_INC(lat_parsing_rem);
	  return val;
	}
      else
	{
	  PARSE_END_INC(lat_parsing_rem);
	  return 0;
	}
    }
}
Esempio n. 8
0
/*
 * Function optimistic_insert stands for the add method of the original paper.
 * Unlocking and freeing the memory are done at the right places.
 */
int
optimistic_insert(sl_intset_t *set, skey_t key, sval_t val)
{
  sl_node_t *succs[HERLIHY_MAX_MAX_LEVEL], *preds[HERLIHY_MAX_MAX_LEVEL];
  sl_node_t  *node_found, *prev_pred, *new_node;
  sl_node_t *pred, *succ;
  int toplevel, highest_locked, i, valid, found;
  unsigned int backoff;

  toplevel = get_rand_level();
  backoff = 1;
	
  PARSE_START_TS(1);
  while (1) 
    {
      UPDATE_TRY();
      found = optimistic_search(set, key, preds, succs, 1);
      PARSE_END_TS(1, lat_parsing_put);

      if (found != -1)
	{
	  node_found = succs[found];
	  if (!node_found->marked)
	    {
	      while (!node_found->fullylinked)
		{
		  PAUSE;
		}
	      PARSE_END_INC(lat_parsing_put);
	      return 0;
	    }
	  continue;
	}

      GL_LOCK(set->lock);		/* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
      highest_locked = -1;
      prev_pred = NULL;
      valid = 1;
      for (i = 0; valid && (i < toplevel); i++)
	{
	  pred = preds[i];
	  succ = succs[i];
	  if (pred != prev_pred)
	    {
	      LOCK(ND_GET_LOCK(pred));
	      highest_locked = i;
	      prev_pred = pred;
	    }	
			
	  valid = (!pred->marked && !succ->marked && 
		   ((volatile sl_node_t*) pred->next[i] == 
		    (volatile sl_node_t*) succ));
	}
	
      if (!valid) 
	{			 /* Unlock the predecessors before leaving */ 
	  unlock_levels(set, preds, highest_locked); /* unlocks the global-lock in the GL case */
	  if (backoff > 5000) 
	    {
	      nop_rep(backoff & MAX_BACKOFF);
	    }
	  backoff <<= 1;
	  continue;
	}
		
      new_node = sl_new_simple_node(key, val, toplevel, 0);

      for (i = 0; i < toplevel; i++)
	{
	  new_node->next[i] = succs[i];
	}

#if defined(__tile__)
      MEM_BARRIER;
#endif

      for (i = 0; i < toplevel; i++)
	{
	  preds[i]->next[i] = new_node;
	}
		
      new_node->fullylinked = 1;

      unlock_levels(set, preds, highest_locked);
      PARSE_END_INC(lat_parsing_put);
      return 1;
    }
}
Esempio n. 9
0
sval_t
alistarh_deleteMin(sl_intset_t *set)
{
    skey_t key;
    sval_t result;
    sl_node_t *next, *node;
    sl_node_t *update[HERLIHY_MAX_MAX_LEVEL];
    sl_node_t *succ, *pred;
    int i, level, continue_flag;

retry:
    if (unlikely(rand_range(100) <= cleaner_percentage))
    {   //become cleaner
        result = 0;
        PARSE_START_TS(4);
        node = last_dummy_entry->next[0];
        while(node->next[0]!=NULL && result==0)
        {
            if (unlikely(node->key > node->next[0]->key))
            {
                node = node->next[0];
                continue;
            }

            succ = NULL;
            pred = set->head;
            key = node->key;
            continue_flag = 0;

            for (level = levelmax - 1; level >= 0; level--)
            {
                succ = pred->next[level];
                while (succ->key < key)
                {
                    pred = succ;
                    succ = succ->next[level];
                }
                update[level] = pred;
            }
            PARSE_END_TS(3, lat_parsing_deleteMin++);

            GL_LOCK(set->lock);

            succ = pred;
            int is_garbage;
            do
            {
                succ = succ->next[0];
                if (succ->key > key)
                {
                    GL_UNLOCK(set->lock);
                    continue_flag = 1;
                    break;
                }

                LOCK(ND_GET_LOCK(succ));
                is_garbage = (succ->key > succ->next[0]->key);
                if (is_garbage || succ->key != key)
                {
                    UNLOCK(ND_GET_LOCK(succ));
                }
                else
                {
                    break;
                }
            } while(true);

            if (continue_flag)
            {
                node = node->next[0];
                continue;
            }

            for (level = succ->toplevel - 1; level >= 0; level--)
            {
                pred = get_lock(update[level], key, level);
                pred->next[level] = succ->next[level];
                succ->next[level] = pred;	// pointer reversal! :-)
                UNLOCK(ND_GET_LOCK(pred));
            }

            result = node->val;

            UNLOCK(ND_GET_LOCK(succ));
            GL_UNLOCK(set->lock);
#if GC == 1
            ssmem_free(alloc, (void*) succ);
#endif
        }
        PARSE_END_TS(4, lat_parsing_cleaner++);

        return result;
    }
    else //spray & mark as deleted
    {
        UPDATE_TRY();

        PARSE_START_TS(3);
        result = 0;
        node = set->head;
        next = NULL;
        for(level = starting_height; level>=0; level-=ALISTARH_LEVELS_TO_DESCEND)
        {
            i = (int)rand_range(max_jump_length);
            for (; i>0; i--)
            {
                next = node->next[level];
                if (next==NULL || next->next[0]==NULL)
                    break;
                node = next;
            }
        }

        if (unlikely(node == set->head))
            goto retry;

        if (unlikely(node->val == KEY_MIN+1))
            goto retry;

        if (unlikely(node->key > node->next[0]->key))
            goto retry;

        succ = NULL;
        pred = set->head;
        key = node->key;

        for (level = levelmax - 1; level >= 0; level--)
        {
            succ = pred->next[level];
            while (succ->key < key)
            {
                pred = succ;
                succ = succ->next[level];
            }
            update[level] = pred;
        }
        PARSE_END_TS(3, lat_parsing_deleteMin++);

        GL_LOCK(set->lock);

        succ = pred;
        int is_garbage;
        do
        {
            succ = succ->next[0];
            if (succ->key > key)
            {
                GL_UNLOCK(set->lock);
                goto retry;
            }

            LOCK(ND_GET_LOCK(succ));
            is_garbage = (succ->key > succ->next[0]->key);
            if (is_garbage || succ->key != key)
            {
                UNLOCK(ND_GET_LOCK(succ));
            }
            else
            {
                break;
            }
        }
        while(true);

        for (level = succ->toplevel - 1; level >= 0; level--)
        {
            pred = get_lock(update[level], key, level);
            pred->next[level] = succ->next[level];
            succ->next[level] = pred;	// pointer reversal! :-)
            UNLOCK(ND_GET_LOCK(pred));
        }

        result = node->val;

        UNLOCK(ND_GET_LOCK(succ));
        GL_UNLOCK(set->lock);
#if GC == 1
        ssmem_free(alloc, (void*) succ);
#endif

        return result;
    }
}
Esempio n. 10
0
sval_t
optimistic_delete(sl_intset_t *set, skey_t key)
{
    PARSE_TRY();
    UPDATE_TRY();
    PARSE_START_TS(2);
    sl_node_t* update[HERLIHY_MAX_MAX_LEVEL];
    sl_node_t* succ = NULL;
    sl_node_t* pred = set->head;
    int lvl;
    for (lvl = levelmax - 1; lvl >= 0; lvl--)
    {
        succ = pred->next[lvl];
        while (succ->key < key)
        {
            pred = succ;
            succ = succ->next[lvl];
        }
        update[lvl] = pred;
    }
    PARSE_END_TS(2, lat_parsing_rem++);

    GL_LOCK(set->lock);

    succ = pred;
    int is_garbage;
    do
    {
        succ = succ->next[0];
        if (succ->key > key)
        {
            GL_UNLOCK(set->lock);
            return false;
        }

        LOCK(ND_GET_LOCK(succ));
        is_garbage = (succ->key > succ->next[0]->key);
        if (is_garbage || succ->key != key)
        {
            UNLOCK(ND_GET_LOCK(succ));
        }
        else
        {
            break;
        }
    }
    while(true);

    for (lvl = succ->toplevel - 1; lvl >= 0; lvl--)
    {
        pred = get_lock(update[lvl], key, lvl);
        pred->next[lvl] = succ->next[lvl];
        succ->next[lvl] = pred;	/* pointer reversal! :-) */
        UNLOCK(ND_GET_LOCK(pred));
    }

    UNLOCK(ND_GET_LOCK(succ));
    GL_UNLOCK(set->lock);
#if GC == 1
    ssmem_free(alloc, (void*) succ);
#endif

    return succ->val;
}
Esempio n. 11
0
int
optimistic_insert(sl_intset_t *set, skey_t key, sval_t val)
{
    PARSE_TRY();
    UPDATE_TRY();
    PARSE_START_TS(1);
    sl_node_t* update[HERLIHY_MAX_MAX_LEVEL];
    sl_node_t* succ;
    sl_node_t* pred = set->head;
    int lvl;
    for (lvl = levelmax - 1; lvl >= 0; lvl--)
    {
        succ = pred->next[lvl];
        while (succ->key < key)
        {
            pred = succ;
            succ = succ->next[lvl];
        }
        if (unlikely(succ->key == key))	/* at any search level */
        {
            return false;
        }
        update[lvl] = pred;
    }
    PARSE_END_TS(1, lat_parsing_put++);

    int rand_lvl = get_rand_level(); /* do the rand_lvl outside the CS */

    GL_LOCK(set->lock);
    pred = get_lock(pred, key, 0);
    if (unlikely(pred->next[0]->key == key))
    {
        UNLOCK(ND_GET_LOCK(pred));
        GL_UNLOCK(set->lock);
        return false;
    }

    sl_node_t* n = sl_new_simple_node(key, val, rand_lvl, 0);
    LOCK(ND_GET_LOCK(n));

    n->next[0] = pred->next[0];	/* we already hold the lock for lvl 0 */
#ifdef __tile__
    MEM_BARRIER;
#endif
    pred->next[0] = n;
    UNLOCK(ND_GET_LOCK(pred));

    for (lvl = 1; lvl < n->toplevel; lvl++)
    {
        pred = get_lock(update[lvl], key, lvl);
        n->next[lvl] = pred->next[lvl];
#ifdef __tile__
        MEM_BARRIER;
#endif
        pred->next[lvl] = n;
        UNLOCK(ND_GET_LOCK(pred));
    }
    UNLOCK(ND_GET_LOCK(n));
    GL_UNLOCK(set->lock);

    return 1;
}