Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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 */
}
Пример #5
0
/**
 * Search for a key's position in the ordered list.  Upon return,
 * *left_node points to the left node (and it has a reference) and the
 * return value points to a node that is referenced too.
 */
static struct lf_ordlist_node *search(struct lf_ordlist *lst,
				      void *key,
				      struct lf_ordlist_node **left_node)
{
	struct lf_ordlist_node *left_node_next, *right_node;
	struct lf_ordlist_node *t, *t_next;

search_again:
	for ( ; ; ) {
		*left_node = left_node_next = NULL;
		t = mem_safe_read(lst->fl, &lst->head);
		t_next = mem_safe_read(lst->fl, &NEXT(lst->head));

		/* 1: Find left_node and right_node
		 *
		 * Entering this loop: t and t_next are referenced.
		 *
		 * Leaving this loop: t is referenced, and if t_next
		 *                    is not marked then *left_node
		 *                    and left_node_next are set and
		 *                    have their own references.  If t
		 *                    != lst->tail, then t_next is
		 *                    also referenced.
		 */
		do {
			if (!IS_MARKED(t_next)) {
				/* these refs may have been copied
				 * before, but we had to loop again */
				if (*left_node) {
					mem_release(lst->fl, *left_node);
					*left_node = NULL;
				}
				if (left_node_next) {
					mem_release(lst->fl, left_node_next);
					left_node_next = NULL;
				}

				/* copy both t and t_next's refs */
				mem_incr_ref(t);
				(*left_node) = t;
				mem_incr_ref(t_next);
				left_node_next = t_next;
			}

			mem_release(lst->fl, t);
			t = GET_UNMARKED(t_next); /* take t_next's ref */

			if (t == lst->tail)
				break;

			t_next = mem_safe_read(lst->fl, &NEXT(t));
		} while (IS_MARKED(t_next) || lst->cmp(t->value, key) < 0);
		if (t != lst->tail)
			mem_release(lst->fl, t_next); /* done with t_next */
		right_node = t;	/* takes t's reference */

		/*
		 * At this point, right_node, *left_node and
		 * left_node_next all have references.
		 */

		/* 2: Check nodes are adjacent */
		if (left_node_next == right_node) {
			mem_release(lst->fl, left_node_next);
			if (right_node != lst->tail
			    && IS_MARKED(NEXT(right_node))) {
				mem_release(lst->fl, right_node);
				mem_release(lst->fl, *left_node);
				goto search_again;
			} else {
				return right_node;
			}
		}

		/* 3: Remove one or more marked nodes
		 *
		 * Here, left_node_next, right_node and *left_node are
		 * referenced. */

		/* in case CAS succeeds. */
		mem_incr_ref(right_node);
		assert(*left_node != lst->tail);
		if (compare_and_swap(&NEXT(*left_node),
				     (intptr_t) left_node_next,
				     (intptr_t) right_node)) {

			/* one for NEXT(*left_node), one for
			 * 'left_node_next' */
			mem_release(lst->fl, left_node_next);
			mem_release(lst->fl, left_node_next);

			if ((right_node != lst->tail)
			    && IS_MARKED(NEXT(right_node))) {
				mem_release(lst->fl, right_node);
				mem_release(lst->fl, *left_node);
				goto search_again;
			} else {
				return right_node;
			}
		}
		/* one for the CAS prep. ref and one for
		 * 'right_node' */
		mem_release(lst->fl, right_node);
		mem_release(lst->fl, right_node);

		mem_release(lst->fl, *left_node);
		mem_release(lst->fl, left_node_next);

	} /* for( ; ; ) */

	/* should not reach here */
	assert(0);
}