Example #1
0
sval_t
lockc_find(intset_l_t *set, skey_t key) 
{
  PARSE_TRY();

  node_l_t *curr, *next; 
  sval_t res = 0;
	
  GL_LOCK(set->lock);		/* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
  LOCK(ND_GET_LOCK(set->head));
  curr = set->head;
  LOCK(ND_GET_LOCK(curr->next));
  next = curr->next;
	
  while (next->key < key) 
    {
      UNLOCK(ND_GET_LOCK(curr));
      curr = next;
      LOCK(ND_GET_LOCK(next->next));
      next = curr->next;
    }	
  if (key == next->key)
    {
      res = next->val;
    }
  GL_UNLOCK(set->lock);
  UNLOCK(ND_GET_LOCK(curr));
  UNLOCK(ND_GET_LOCK(next));
  return res;
}
Example #2
0
sval_t
cpy_delete(copy_on_write_t* set, skey_t key)
{
  size_t bucket = key & set->hash;
  array_ll_t* all_old;

#if CPY_ON_WRITE_READ_ONLY_FAIL == 1
  all_old = (array_ll_t*) set->array[bucket];
  if (cpy_array_search(all_old, key) == 0)
    {
      return 0;
    }
#endif

  sval_t removed = 0;

  GL_LOCK(set->lock);
  LOCK(set->lock + bucket);
  all_old = (array_ll_t*) set->array[bucket];
  array_ll_t* all_new = array_ll_new(all_old->size - 1);

  int i, n;
  for (i = 0, n = 0; i < all_old->size; i++, n++)
    {
      if (unlikely(all_old->kvs[i].key == key))
	{
	  removed = all_old->kvs[i].val;
	  n--;
	  continue;
	}

      all_new->kvs[n].key = all_old->kvs[i].key;
      all_new->kvs[n].val = all_old->kvs[i].val;
    }

  if (removed)
    {
      set->array[bucket] = all_new;
      ssmem_free(alloc, (void*) all_old);
    }
  else
    {
      ssmem_free(alloc, (void*) all_new);
    }

  GL_UNLOCK(set->lock);
  UNLOCK(set->lock + bucket);
  return removed;
}
Example #3
0
/*
 * Logically remove an element by setting a mark bit to 1 
 * before removing it physically.
 */
sval_t
parse_delete(intset_l_t *set, skey_t key)
{
  node_l_t *pred, *curr;
  sval_t result = 0;
  int done = 0;
	
  do
    {
      PARSE_TRY();
      pred = set->head;
      curr = pred->next;
      while (likely(curr->key < key))
	{
	  pred = curr;
	  curr = curr->next;
	}

      UPDATE_TRY();

      GL_LOCK(set->lock);		/* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
      LOCK(ND_GET_LOCK(pred));
      LOCK(ND_GET_LOCK(curr));

      if (parse_validate(pred, curr))
	{
	  if (key == curr->key)
	    {
	      result = curr->val;
	      node_l_t* c_nxt = curr->next;
	      curr->marked = 1;
	      pred->next = c_nxt;
#if GC == 1
	      ssmem_free(alloc, (void*) curr);
#endif
	    }
	  done = 1;
	}

      GL_UNLOCK(set->lock);
      UNLOCK(ND_GET_LOCK(curr));
      UNLOCK(ND_GET_LOCK(pred));
    }
  while (!done);
  return result;
}
Example #4
0
int
cpy_insert(copy_on_write_t* set, skey_t key, sval_t val) 
{
  size_t bucket = key & set->hash;
  array_ll_t* all_old;

#if CPY_ON_WRITE_READ_ONLY_FAIL == 1
  all_old = (array_ll_t*) set->array[bucket];
  if (cpy_array_search(all_old, key) == 1)
    {
      return 0;
    }
#endif

  GL_LOCK(set->lock);
  LOCK(set->lock + bucket);

  all_old = (array_ll_t*) set->array[bucket];
  array_ll_t* all_new = array_ll_new(all_old->size + 1);

  int i;
  for (i = 0; i < all_old->size; i++)
    {
      if (unlikely(all_old->kvs[i].key == key))
	{
	  ssmem_free(alloc, (void*) all_new);
	  GL_UNLOCK(set->lock);
	  UNLOCK(set->lock + bucket);
	  return 0;
	}
      all_new->kvs[i].key = all_old->kvs[i].key;
      all_new->kvs[i].val = all_old->kvs[i].val;
    }

  all_new->kvs[i].key = key;
  all_new->kvs[i].val = val;
  
  set->array[bucket] = all_new;
  ssmem_free(alloc, (void*) all_old);

  GL_UNLOCK(set->lock);
  UNLOCK(set->lock + bucket);
  return 1;
}
Example #5
0
int
parse_insert(intset_l_t *set, skey_t key, sval_t val)
{
  node_l_t *curr, *pred, *newnode;
  int result = -1;
	
  do
    {
      PARSE_TRY();
      pred = set->head;
      curr = pred->next;
      while (likely(curr->key < key))
	{
	  pred = curr;
	  curr = curr->next;
	}

      UPDATE_TRY();

      GL_LOCK(set->lock);		/* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
      LOCK(ND_GET_LOCK(pred));
      LOCK(ND_GET_LOCK(curr));

      if (parse_validate(pred, curr))
	{
	  result = (curr->key != key);
	  if (result) 
	    {
	      newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif
	      pred->next = newnode;
	    } 
	}
      GL_UNLOCK(set->lock);
      UNLOCK(ND_GET_LOCK(curr)); 
      UNLOCK(ND_GET_LOCK(pred));
    }
  while (result < 0);
  return result;
}
Example #6
0
int
lockc_insert(intset_l_t *set, skey_t key, sval_t val) 
{
  PARSE_TRY();
  UPDATE_TRY();

  node_l_t *curr, *next, *newnode;
  int found;
	
  GL_LOCK(set->lock);		/* when GL_[UN]LOCK is defined the [UN]LOCK is not ;-) */
  LOCK(ND_GET_LOCK(set->head));
  curr = set->head;
  LOCK(ND_GET_LOCK(curr->next));
  next = curr->next;
	
  while (next->key < key) 
    {
      UNLOCK(ND_GET_LOCK(curr));
      curr = next;
      LOCK(ND_GET_LOCK(next->next));
      next = curr->next;
    }
  found = (key == next->key);
  if (!found) 
    {
      newnode =  new_node_l(key, val, next, 1);
#ifdef __tile__
  MEM_BARRIER;
#endif
      curr->next = newnode;
    }
  GL_UNLOCK(set->lock);
  UNLOCK(ND_GET_LOCK(curr));
  UNLOCK(ND_GET_LOCK(next));
  return !found;
}
Example #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;
	}
    }
}
Example #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;
    }
}
Example #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;
    }
}
Example #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;
}
Example #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;
}