src/hotspot/share/utilities/lockFreeStack.hpp
author stefank
Mon, 25 Nov 2019 12:32:40 +0100
changeset 59251 4cbfa5077d68
parent 59248 e92153ed8bdc
child 59252 623722a6aeb9
permissions -rw-r--r--
8234739: Harmonize parameter order in Atomic - xchg Reviewed-by: rehn, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     1
/*
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     4
 *
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     7
 * published by the Free Software Foundation.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     8
 *
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    13
 * accompanied this code).
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    14
 *
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    18
 *
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    21
 * questions.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    22
 *
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    23
 */
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    24
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    25
#ifndef SHARE_UTILITIES_LOCKFREESTACK_HPP
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    26
#define SHARE_UTILITIES_LOCKFREESTACK_HPP
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    27
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    28
#include "runtime/atomic.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    29
#include "utilities/debug.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    30
#include "utilities/macros.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    31
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    32
// The LockFreeStack class template provides a lock-free LIFO. The objects
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    33
// in the sequence are intrusively linked via a member in the objects.  As
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    34
// a result, there is no allocation involved in adding objects to the stack
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    35
// or removing them from the stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    36
//
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    37
// To be used in a LockFreeStack of objects of type T, an object of
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    38
// type T must have a list entry member of type T* volatile, with an
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    39
// non-member accessor function returning a pointer to that member.  A
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    40
// LockFreeStack is associated with the class of its elements and an
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    41
// entry member from that class.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    42
//
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    43
// An object can be in multiple stacks at the same time, so long as
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    44
// each stack uses a different entry member. That is, the class of the
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    45
// object must have multiple LockFreeStack entry members, one for each
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    46
// stack in which the object may simultaneously be an element.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    47
//
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    48
// LockFreeStacks support polymorphic elements.  Because the objects
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    49
// in a stack are externally managed, rather than being embedded
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    50
// values in the stack, the actual type of such objects may be more
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    51
// specific than the stack's element type.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    52
//
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    53
// \tparam T is the class of the elements in the stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    54
//
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    55
// \tparam next_ptr is a function pointer.  Applying this function to
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    56
// an object of type T must return a pointer to the list entry member
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    57
// of the object associated with the LockFreeStack type.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    58
template<typename T, T* volatile* (*next_ptr)(T&)>
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    59
class LockFreeStack {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    60
  T* volatile _top;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    61
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    62
  void prepend_impl(T* first, T* last) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    63
    T* cur = top();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    64
    T* old;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    65
    do {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    66
      old = cur;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    67
      set_next(*last, cur);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    68
      cur = Atomic::cmpxchg(first, &_top, cur);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    69
    } while (old != cur);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    70
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    71
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    72
  // Noncopyable.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    73
  LockFreeStack(const LockFreeStack&);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    74
  LockFreeStack& operator=(const LockFreeStack&);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    75
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    76
public:
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    77
  LockFreeStack() : _top(NULL) {}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    78
  ~LockFreeStack() { assert(empty(), "stack not empty"); }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    79
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    80
  // Atomically removes the top object from this stack and returns a
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    81
  // pointer to that object, or NULL if this stack is empty. Acts as a
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    82
  // full memory barrier. Subject to ABA behavior; callers must ensure
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    83
  // usage is safe.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    84
  T* pop() {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    85
    T* result = top();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    86
    T* old;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    87
    do {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    88
      old = result;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    89
      T* new_top = NULL;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    90
      if (result != NULL) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    91
        new_top = next(*result);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    92
      }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    93
      // CAS even on empty pop, for consistent membar bahavior.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    94
      result = Atomic::cmpxchg(new_top, &_top, result);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    95
    } while (result != old);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    96
    if (result != NULL) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    97
      set_next(*result, NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    98
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    99
    return result;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   100
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   101
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   102
  // Atomically exchange the list of elements with NULL, returning the old
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   103
  // list of elements.  Acts as a full memory barrier.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   104
  // postcondition: empty()
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   105
  T* pop_all() {
59251
4cbfa5077d68 8234739: Harmonize parameter order in Atomic - xchg
stefank
parents: 59248
diff changeset
   106
    return Atomic::xchg(&_top, (T*)NULL);
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   107
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   108
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   109
  // Atomically adds value to the top of this stack.  Acts as a full
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   110
  // memory barrier.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   111
  void push(T& value) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   112
    assert(next(value) == NULL, "precondition");
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   113
    prepend_impl(&value, &value);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   114
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   115
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   116
  // Atomically adds the list of objects (designated by first and
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   117
  // last) before the objects already in this stack, in the same order
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   118
  // as in the list. Acts as a full memory barrier.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   119
  // precondition: next(last) == NULL.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   120
  // postcondition: top() == &first, next(last) == old top().
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   121
  void prepend(T& first, T& last) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   122
    assert(next(last) == NULL, "precondition");
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   123
#ifdef ASSERT
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   124
    for (T* p = &first; p != &last; p = next(*p)) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   125
      assert(p != NULL, "invalid prepend list");
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   126
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   127
#endif
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   128
    prepend_impl(&first, &last);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   129
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   130
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   131
  // Atomically adds the list of objects headed by first before the
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   132
  // objects already in this stack, in the same order as in the list.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   133
  // Acts as a full memory barrier.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   134
  // postcondition: top() == &first.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   135
  void prepend(T& first) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   136
    T* last = &first;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   137
    while (true) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   138
      T* step_to = next(*last);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   139
      if (step_to == NULL) break;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   140
      last = step_to;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   141
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   142
    prepend_impl(&first, last);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   143
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   144
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   145
  // Return true if the stack is empty.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   146
  bool empty() const { return top() == NULL; }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   147
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   148
  // Return the most recently pushed element, or NULL if the stack is empty.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   149
  // The returned element is not removed from the stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   150
  T* top() const { return Atomic::load(&_top); }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   151
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   152
  // Return the number of objects in the stack.  There must be no concurrent
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   153
  // pops while the length is being determined.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   154
  size_t length() const {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   155
    size_t result = 0;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   156
    for (const T* current = top(); current != NULL; current = next(*current)) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   157
      ++result;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   158
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   159
    return result;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   160
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   161
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   162
  // Return the entry following value in the list used by the
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   163
  // specialized LockFreeStack class.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   164
  static T* next(const T& value) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   165
    return Atomic::load(next_ptr(const_cast<T&>(value)));
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   166
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   167
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   168
  // Set the entry following value to new_next in the list used by the
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   169
  // specialized LockFreeStack class.  Not thread-safe; in particular,
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   170
  // if value is in an instance of this specialization of LockFreeStack,
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   171
  // there must be no concurrent push or pop operations on that stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   172
  static void set_next(T& value, T* new_next) {
59248
e92153ed8bdc 8234736: Harmonize parameter order in Atomic - store
stefank
parents: 53404
diff changeset
   173
    Atomic::store(next_ptr(value), new_next);
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   174
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   175
};
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   176
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   177
#endif // SHARE_UTILITIES_LOCKFREESTACK_HPP