コード例 #1
0
ファイル: alistarh_pugh.c プロジェクト: wuma123/ASCYLIB-1
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;
}
コード例 #2
0
ファイル: herlihy.c プロジェクト: digideskio/ASCYLIB
inline sl_node_t*
optimistic_left_search(sl_intset_t *set, skey_t key)
{
  PARSE_TRY();
  int i;
  sl_node_t *pred, *curr, *nd = NULL;
	
  pred = set->head;
	
  for (i = (pred->toplevel - 1); i >= 0; i--)
    {
      curr = pred->next[i];
      while (key > curr->key)
	{
	  pred = curr;
	  curr = pred->next[i];
	}

      if (key == curr->key)
	{
	  nd = curr;
	  break;
	}
    }

  return nd;
}
コード例 #3
0
ファイル: lotanshavit_lf.c プロジェクト: LPD-EPFL/ASCYLIB
int				
fraser_search_no_cleanup_succs(sl_intset_t *set, skey_t key, sl_node_t **right_list)
{
  PARSE_TRY();

  int i;
  sl_node_t *left, *left_next, *right = NULL;

  left = set->head;
  for (i = levelmax - 1; i >= 0; i--)
    {
      left_next = GET_UNMARKED(left->next[i]);
      right = left_next;
      while (1)
	{
	  if (likely(!IS_MARKED(right->next[i])))
	    {
	      if (right->key >= key)
		{
		  break;
		}
	      left = right;
	    }
	  right = GET_UNMARKED(right->next[i]);
	}


      right_list[i] = right;
    }
  return (right->key == key);
}
コード例 #4
0
ファイル: coupling.c プロジェクト: digideskio/ASCYLIB
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;
}
コード例 #5
0
ファイル: herlihy.c プロジェクト: digideskio/ASCYLIB
/*
 * Function optimistic_search corresponds to the findNode method of the 
 * original paper. A fast parameter has been added to speed-up the search 
 * so that the function quits as soon as the searched element is found.
 */
inline int
optimistic_search(sl_intset_t *set, skey_t key, sl_node_t **preds, sl_node_t **succs, int fast)
{
  PARSE_TRY();
  int found, i;
  sl_node_t *pred, *curr;
	
  found = -1;
  pred = set->head;
	
  for (i = (pred->toplevel - 1); i >= 0; i--)
    {
      curr = pred->next[i];
      while (key > curr->key)
	{
	  pred = curr;
	  curr = pred->next[i];
	}
      if (preds != NULL) 
	preds[i] = pred;
      succs[i] = curr;
      if (found == -1 && key == curr->key)
	{
	  found = i;
	}
    }
  return found;
}
コード例 #6
0
ファイル: lotanshavit_lf.c プロジェクト: LPD-EPFL/ASCYLIB
static sl_node_t* 
fraser_left_search(sl_intset_t *set, skey_t key)
{
  PARSE_TRY();
  sl_node_t* left = NULL;
  sl_node_t* left_prev;
  
  left_prev = set->head;
  int lvl;  
  for (lvl = levelmax - 1; lvl >= 0; lvl--)
    {
      left = GET_UNMARKED(left_prev->next[lvl]);
      while(left->key < key || IS_MARKED(left->next[lvl]))
      	{
      	  if (!IS_MARKED(left->next[lvl]))
      	    {
      	      left_prev = left;
      	    }
      	  left = GET_UNMARKED(left->next[lvl]);
      	}

      if ((left->key == key))
	{
	  break;
	}
    }
  return left;
}
コード例 #7
0
ファイル: linkedlist-optik.c プロジェクト: LPD-EPFL/ASCYLIB
/*   
 *   File: optik.c
 *   Author: Vasileios Trigonakis <*****@*****.**>
 *   Description: 
 *
 * Copyright (c) 2014 Vasileios Trigonakis <*****@*****.**>,
 *	      	      Distributed Programming Lab (LPD), EPFL
 *
 * ASCYLIB is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, version 2
 * of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include "linkedlist-optik.h"

RETRY_STATS_VARS;

sval_t
optik_find(intset_l_t *set, skey_t key)
{
  PARSE_TRY();
  node_l_t* curr = set->head;
  while (curr != NULL && curr->key < key)
    {
      curr = curr->next;
    }

  sval_t res = 0;
  if (curr != NULL && curr->key == key)
    {
      res = curr->val;
    }

  return res;
}

#if !defined(LL_GLOBAL_LOCK)
int
optik_insert(intset_l_t *set, skey_t key, sval_t val)
{	
 restart:
  PARSE_TRY();
  volatile node_l_t *curr, *pred = NULL;

  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);
  curr = set->head;

  while (curr != NULL && (curr->key < key))
    {
      pred = curr;
      curr = curr->next;
    }

  UPDATE_TRY();

  if (curr != NULL && curr->key == key)
    {
      return false;
    }

  if (!optik_trylock_version(&set->lock, pred_ver))
    {
      goto restart;
    }

  node_l_t* newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif

  if (pred != NULL)
    {
      pred->next = newnode;
    }
  else
    {
      set->head = newnode;
    }

  optik_unlock(&set->lock);

  return true;
}
#else  /* LL_GLOBAL_LOCK == 1 :: pessimistic */
int
optik_insert(intset_l_t *set, skey_t key, sval_t val)
{	
  volatile node_l_t *curr, *pred;
  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);

  int r;
  for (r = 0; r < 2; r++)
    {
      PARSE_TRY();

      pred = NULL;
      curr = set->head;

      while (curr != NULL && curr->key < key)
	{
	  pred = curr;
	  curr = curr->next;
	}

      UPDATE_TRY();

      if (curr != NULL && curr->key == key)
	{
	  if (r)
	    {
	      optik_unlock(&set->lock);
	    }
	  return false;
	}

      if (!r && optik_lock_version(&set->lock, pred_ver))
	{
	  break;
	}
    }

  node_l_t* newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif

  if (pred != NULL)
    {
      pred->next = newnode;
    }
  else
    {
      set->head = newnode;
    }

  optik_unlock(&set->lock);

  return true;
}
コード例 #8
0
ファイル: linkedlist-optik.c プロジェクト: LPD-EPFL/ASCYLIB
/*   
 *   File: optik.c
 *   Author: Vasileios Trigonakis <*****@*****.**>
 *   Description: 
 *
 * Copyright (c) 2014 Vasileios Trigonakis <*****@*****.**>,
 *	      	      Distributed Programming Lab (LPD), EPFL
 *
 * ASCYLIB is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, version 2
 * of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include "linkedlist-optik.h"

RETRY_STATS_VARS;

sval_t
optik_find(intset_l_t *set, skey_t key)
{
  PARSE_TRY();
  node_l_t* curr = set->head;
  while (curr != NULL && curr->key < key)
    {
      curr = curr->next;
    }

  sval_t res = 0;
  if (curr != NULL && curr->key == key)
    {
      res = curr->val;
    }

  return res;
}

#if !defined(LL_GLOBAL_LOCK)
int
optik_insert(intset_l_t *set, skey_t key, sval_t val)
{	
 restart:
  PARSE_TRY();
  volatile node_l_t *curr, *pred = NULL;

  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);
  curr = set->head;

  while (curr != NULL && (curr->key < key))
    {
      pred = curr;
      curr = curr->next;
    }

  UPDATE_TRY();

  if (curr != NULL && curr->key == key)
    {
      return false;
    }

  if (!optik_trylock_version(&set->lock, pred_ver))
    {
      goto restart;
    }

  node_l_t* newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif

  if (pred != NULL)
    {
      pred->next = newnode;
    }
  else
    {
      set->head = newnode;
    }

  optik_unlock(&set->lock);

  return true;
}
#else  /* LL_GLOBAL_LOCK == 1 :: pessimistic */
int
optik_insert(intset_l_t *set, skey_t key, sval_t val)
{	
  volatile node_l_t *curr, *pred;
  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);

  int r;
  for (r = 0; r < 2; r++)
    {
      PARSE_TRY();

      pred = NULL;
      curr = set->head;

      while (curr != NULL && curr->key < key)
	{
	  pred = curr;
	  curr = curr->next;
	}

      UPDATE_TRY();

      if (curr != NULL && curr->key == key)
	{
	  if (r)
	    {
	      optik_unlock(&set->lock);
	    }
	  return false;
	}

      if (!r && optik_lock_version(&set->lock, pred_ver))
	{
	  break;
	}
    }

  node_l_t* newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif

  if (pred != NULL)
    {
      pred->next = newnode;
    }
  else
    {
      set->head = newnode;
    }

  optik_unlock(&set->lock);

  return true;
}
#endif	/* LL_GLOBAL_LOCK */

#if !defined(LL_GLOBAL_LOCK)
sval_t
optik_delete(intset_l_t *set, skey_t key)
{
 restart:
  PARSE_TRY();
  volatile node_l_t *pred = NULL, *curr;  
  sval_t result = 0;

  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);
  curr = set->head;

  while (curr != NULL && curr->key < key)
    {
      pred = curr;
      curr = curr->next;
    }

  UPDATE_TRY();

  if (curr == NULL || curr->key != key)
    {
      return false;
    }

  if ((!optik_trylock_version(&set->lock, pred_ver)))
    {
      goto restart;
    }

  result = curr->val;
  if (pred != NULL)
    {
      pred->next = curr->next;
    }
  else
    {
      set->head = curr->next;
    }

  optik_unlock(&set->lock);
     
#if GC == 1
   ssmem_free(alloc, (void*) curr);
#endif
 
  return result;
}
#else  /* LL_GLOBAL_LOCK = 1 :: pessimistic locking */
sval_t
optik_delete(intset_l_t *set, skey_t key)
{
  volatile node_l_t *pred, *curr;  
  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);

  int r;
  for (r = 0; r < 2; r++)
    {
      PARSE_TRY();

      pred = NULL;
      curr = set->head;

      while (curr != NULL && curr->key < key)
	{
	  pred = curr;
	  curr = curr->next;
	}

      UPDATE_TRY();

      if (curr == NULL || curr->key != key)
	{
	  if (r)
	    {
	      optik_unlock(&set->lock);
	    }
	  return false;
	}

      if (!r && optik_lock_version(&set->lock, pred_ver))
	{
	  break;
	}
    }

  sval_t result = curr->val;
  if (pred != NULL)
    {
      pred->next = curr->next;
    }
  else
    {
      set->head = curr->next;
    }

  optik_unlock(&set->lock);
     
#if GC == 1
  ssmem_free(alloc, (void*) curr);
#endif
 
  return result;
}
コード例 #9
0
ファイル: lotanshavit_lf.c プロジェクト: LPD-EPFL/ASCYLIB
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);
}
コード例 #10
0
ファイル: linkedlist-optik.c プロジェクト: LPD-EPFL/ASCYLIB
sval_t
optik_delete(intset_l_t *set, skey_t key)
{
 restart:
  PARSE_TRY();
  volatile node_l_t *pred = NULL, *curr;  
  sval_t result = 0;

  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);
  curr = set->head;

  while (curr != NULL && curr->key < key)
    {
      pred = curr;
      curr = curr->next;
    }

  UPDATE_TRY();

  if (curr == NULL || curr->key != key)
    {
      return false;
    }

  if ((!optik_trylock_version(&set->lock, pred_ver)))
    {
      goto restart;
    }

  result = curr->val;
  if (pred != NULL)
    {
      pred->next = curr->next;
    }
  else
    {
      set->head = curr->next;
    }

  optik_unlock(&set->lock);
     
#if GC == 1
   ssmem_free(alloc, (void*) curr);
#endif
 
  return result;
}
コード例 #11
0
ファイル: lazy.c プロジェクト: LPD-EPFL/ASCYLIB
/*
 * 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;
}
コード例 #12
0
ファイル: linkedlist-optik.c プロジェクト: LPD-EPFL/ASCYLIB
int
optik_insert(intset_l_t *set, skey_t key, sval_t val)
{	
 restart:
  PARSE_TRY();
  volatile node_l_t *curr, *pred = NULL;

  COMPILER_NO_REORDER(optik_t pred_ver = set->lock);
  curr = set->head;

  while (curr != NULL && (curr->key < key))
    {
      pred = curr;
      curr = curr->next;
    }

  UPDATE_TRY();

  if (curr != NULL && curr->key == key)
    {
      return false;
    }

  if (!optik_trylock_version(&set->lock, pred_ver))
    {
      goto restart;
    }

  node_l_t* newnode = new_node_l(key, val, curr, 0);
#ifdef __tile__
  MEM_BARRIER;
#endif

  if (pred != NULL)
    {
      pred->next = newnode;
    }
  else
    {
      set->head = newnode;
    }

  optik_unlock(&set->lock);

  return true;
}
コード例 #13
0
ファイル: linkedlist-optik.c プロジェクト: LPD-EPFL/ASCYLIB
sval_t
optik_find(intset_l_t *set, skey_t key)
{
  PARSE_TRY();
  node_l_t* curr = set->head;
  while (curr != NULL && curr->key < key)
    {
      curr = curr->next;
    }

  sval_t res = 0;
  if (curr != NULL && curr->key == key)
    {
      res = curr->val;
    }

  return res;
}
コード例 #14
0
ファイル: lazy.c プロジェクト: LPD-EPFL/ASCYLIB
sval_t
parse_find(intset_l_t *set, skey_t key)
{
  PARSE_TRY();
  node_l_t* curr = set->head;
  while (curr->key < key)
    {
      curr = curr->next;
    }

  sval_t res = 0;
  if ((curr->key == key) && !curr->marked)
    {
      res = curr->val;
    }
  
  return res;
}
コード例 #15
0
ファイル: lazy.c プロジェクト: LPD-EPFL/ASCYLIB
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;
}
コード例 #16
0
ファイル: bst-aravind.c プロジェクト: LPD-EPFL/ASCYLIB
seek_record_t * bst_seek(skey_t key, node_t* node_r){
  PARSE_TRY();
    volatile seek_record_t seek_record_l;
    node_t* node_s = ADDRESS(node_r->left);
    seek_record_l.ancestor = node_r;
    seek_record_l.successor = node_s; 
    seek_record_l.parent = node_s;
    seek_record_l.leaf = ADDRESS(node_s->left);

    node_t* parent_field = (node_t*) seek_record_l.parent->left;
    node_t* current_field = (node_t*) seek_record_l.leaf->left;
    node_t* current = ADDRESS(current_field);


    while (current != NULL) {
        if (!GETTAG(parent_field)) {
            seek_record_l.ancestor = seek_record_l.parent;
            seek_record_l.successor = seek_record_l.leaf;
        }
        seek_record_l.parent = seek_record_l.leaf;
        seek_record_l.leaf = current;

        parent_field = current_field;
        if (key < current->key) {
            current_field= (node_t*) current->left;
        } else {
            current_field= (node_t*) current->right;
        }
        current=ADDRESS(current_field);
    }
    seek_record->ancestor=seek_record_l.ancestor;
    seek_record->successor=seek_record_l.successor;
    seek_record->parent=seek_record_l.parent;
    seek_record->leaf=seek_record_l.leaf;
    return seek_record;
}
コード例 #17
0
ファイル: coupling.c プロジェクト: digideskio/ASCYLIB
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;
}
コード例 #18
0
ファイル: alistarh_pugh.c プロジェクト: wuma123/ASCYLIB-1
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;
}
コード例 #19
0
ファイル: alistarh_pugh.c プロジェクト: wuma123/ASCYLIB-1
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;
}
コード例 #20
0
ファイル: bst_howley.c プロジェクト: LPD-EPFL/ASCYLIB
sval_t bst_find(skey_t k, node_t** pred, operation_t** pred_op, node_t** curr, operation_t** curr_op, node_t* aux_root, node_t* root){

	sval_t result;
	skey_t curr_key;
	node_t* next;
	node_t* last_right;
	operation_t* last_right_op;

retry:
	PARSE_TRY();

	result = NOT_FOUND_R;
	*curr = aux_root;
	*curr_op = (*curr)->op;

	if(GETFLAG(*curr_op) != STATE_OP_NONE){
#ifdef __tile__
    MEM_BARRIER;
#endif
		if (aux_root == root){
			bst_help_child_cas((operation_t*)UNFLAG(*curr_op), *curr, root);
			goto retry;
		} else {
			return ABORT;
		}
	}


	next = (node_t*) (*curr)->right;
	last_right = *curr;
	last_right_op = *curr_op;

	while (!ISNULL(next)){
		*pred = *curr;
		*pred_op = *curr_op;
		*curr = next;
		*curr_op = (*curr)->op;


		if(GETFLAG(*curr_op) != STATE_OP_NONE){
			bst_help(*pred, *pred_op, *curr, *curr_op, root);
			goto retry;
		}
		curr_key = (*curr)->key;
		if(k < curr_key){
			result = NOT_FOUND_L;
			next = (node_t*) (*curr)->left;
		} else if(k > curr_key) {
			result = NOT_FOUND_R;
			next = (node_t*) (*curr)->right;
			last_right = *curr;
			last_right_op = *curr_op;
		} else{
			result = (*curr)->value;
			break;
		}
	}
	
	if ((!(result & val_mask)) && (last_right_op != last_right->op)) {
		goto retry;
	}

	if ((*curr)->op != *curr_op){
		goto retry;
	}

	return result;
}