test/hotspot/gtest/utilities/test_lockFreeStack.cpp
author stefank
Mon, 25 Nov 2019 12:22:13 +0100
changeset 59247 56bf71d64d51
parent 53410 571f12d51db5
permissions -rw-r--r--
8234562: Move OrderAccess::release_store*/load_acquire to Atomic 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
#include "precompiled.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    25
#include "memory/allocation.inline.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    26
#include "runtime/atomic.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    27
#include "utilities/globalDefinitions.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    28
#include "utilities/lockFreeStack.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    29
#include "threadHelper.inline.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    30
#include "unittest.hpp"
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    31
#include <new>
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    32
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    33
class LockFreeStackTestElement {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    34
  typedef LockFreeStackTestElement Element;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    35
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    36
  Element* volatile _entry;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    37
  Element* volatile _entry1;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    38
  size_t _id;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    39
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    40
  static Element* volatile* entry_ptr(Element& e) { return &e._entry; }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    41
  static Element* volatile* entry1_ptr(Element& e) { return &e._entry1; }
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
public:
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    44
  LockFreeStackTestElement(size_t id = 0) : _entry(), _entry1(), _id(id) {}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    45
  size_t id() const { return _id; }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    46
  void set_id(size_t value) { _id = value; }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    47
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
    48
  typedef LockFreeStack<Element, &entry_ptr> TestStack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
    49
  typedef LockFreeStack<Element, &entry1_ptr> TestStack1;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    50
};
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    51
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    52
typedef LockFreeStackTestElement Element;
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
    53
typedef Element::TestStack TestStack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
    54
typedef Element::TestStack1 TestStack1;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    55
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    56
static void initialize_ids(Element* elements, size_t size) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    57
  for (size_t i = 0; i < size; ++i) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    58
    elements[i].set_id(i);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    59
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    60
}
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
class LockFreeStackTestBasics : public ::testing::Test {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    63
public:
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    64
  LockFreeStackTestBasics();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    65
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    66
  static const size_t nelements = 10;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    67
  Element elements[nelements];
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
    68
  TestStack stack;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    69
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    70
private:
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    71
  void initialize();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    72
};
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    73
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    74
const size_t LockFreeStackTestBasics::nelements;
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
LockFreeStackTestBasics::LockFreeStackTestBasics() : stack() {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    77
  initialize_ids(elements, nelements);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    78
  initialize();
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
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    81
void LockFreeStackTestBasics::initialize() {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    82
  ASSERT_TRUE(stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    83
  ASSERT_EQ(0u, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    84
  ASSERT_TRUE(stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    85
  ASSERT_TRUE(stack.top() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    86
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    87
  for (size_t id = 0; id < nelements; ++id) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    88
    ASSERT_EQ(id, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    89
    Element* e = &elements[id];
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    90
    ASSERT_EQ(id, e->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    91
    stack.push(*e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    92
    ASSERT_FALSE(stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    93
    ASSERT_EQ(e, stack.top());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    94
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    95
}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    96
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    97
TEST_F(LockFreeStackTestBasics, push_pop) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    98
  for (size_t i = nelements; i > 0; ) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
    99
    ASSERT_FALSE(stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   100
    ASSERT_EQ(i, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   101
    --i;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   102
    Element* e = stack.pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   103
    ASSERT_TRUE(e != NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   104
    ASSERT_EQ(&elements[i], e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   105
    ASSERT_EQ(i, e->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   106
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   107
  ASSERT_TRUE(stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   108
  ASSERT_EQ(0u, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   109
  ASSERT_TRUE(stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   110
}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   111
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   112
TEST_F(LockFreeStackTestBasics, prepend_one) {
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   113
  TestStack other_stack;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   114
  ASSERT_TRUE(other_stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   115
  ASSERT_TRUE(other_stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   116
  ASSERT_EQ(0u, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   117
  ASSERT_TRUE(other_stack.top() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   118
  ASSERT_TRUE(other_stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   119
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   120
  other_stack.prepend(*stack.pop_all());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   121
  ASSERT_EQ(nelements, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   122
  ASSERT_TRUE(stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   123
  ASSERT_EQ(0u, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   124
  ASSERT_TRUE(stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   125
  ASSERT_TRUE(stack.top() == NULL);
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
  for (size_t i = nelements; i > 0; ) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   128
    ASSERT_EQ(i, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   129
    --i;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   130
    Element* e = other_stack.pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   131
    ASSERT_TRUE(e != NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   132
    ASSERT_EQ(&elements[i], e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   133
    ASSERT_EQ(i, e->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   134
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   135
  ASSERT_EQ(0u, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   136
  ASSERT_TRUE(other_stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   137
}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   138
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   139
TEST_F(LockFreeStackTestBasics, prepend_two) {
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   140
  TestStack other_stack;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   141
  ASSERT_TRUE(other_stack.empty());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   142
  ASSERT_EQ(0u, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   143
  ASSERT_TRUE(other_stack.top() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   144
  ASSERT_TRUE(other_stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   145
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   146
  Element* top = stack.pop_all();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   147
  ASSERT_EQ(top, &elements[nelements - 1]);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   148
  other_stack.prepend(*top, elements[0]);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   149
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   150
  for (size_t i = nelements; i > 0; ) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   151
    ASSERT_EQ(i, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   152
    --i;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   153
    Element* e = other_stack.pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   154
    ASSERT_TRUE(e != NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   155
    ASSERT_EQ(&elements[i], e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   156
    ASSERT_EQ(i, e->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   157
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   158
  ASSERT_EQ(0u, other_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   159
  ASSERT_TRUE(other_stack.pop() == NULL);
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
TEST_F(LockFreeStackTestBasics, two_stacks) {
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   163
  TestStack1 stack1;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   164
  ASSERT_TRUE(stack1.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   165
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   166
  for (size_t id = 0; id < nelements; ++id) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   167
    stack1.push(elements[id]);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   168
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   169
  ASSERT_EQ(nelements, stack1.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   170
  Element* e0 = stack.top();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   171
  Element* e1 = stack1.top();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   172
  while (true) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   173
    ASSERT_EQ(e0, e1);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   174
    if (e0 == NULL) break;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   175
    e0 = stack.next(*e0);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   176
    e1 = stack1.next(*e1);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   177
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   178
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   179
  for (size_t i = nelements; i > 0; ) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   180
    ASSERT_EQ(i, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   181
    ASSERT_EQ(i, stack1.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   182
    --i;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   183
    Element* e = stack.pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   184
    ASSERT_TRUE(e != NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   185
    ASSERT_EQ(&elements[i], e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   186
    ASSERT_EQ(i, e->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   187
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   188
    Element* e1 = stack1.pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   189
    ASSERT_TRUE(e1 != NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   190
    ASSERT_EQ(&elements[i], e1);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   191
    ASSERT_EQ(i, e1->id());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   192
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   193
    ASSERT_EQ(e, e1);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   194
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   195
  ASSERT_EQ(0u, stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   196
  ASSERT_EQ(0u, stack1.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   197
  ASSERT_TRUE(stack.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   198
  ASSERT_TRUE(stack1.pop() == NULL);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   199
}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   200
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   201
class LockFreeStackTestThread : public JavaTestThread {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   202
  uint _id;
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   203
  TestStack* _from;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   204
  TestStack* _to;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   205
  volatile size_t* _processed;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   206
  size_t _process_limit;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   207
  size_t _local_processed;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   208
  volatile bool _ready;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   209
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   210
public:
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   211
  LockFreeStackTestThread(Semaphore* post,
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   212
                          uint id,
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   213
                          TestStack* from,
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   214
                          TestStack* to,
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   215
                          volatile size_t* processed,
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   216
                          size_t process_limit) :
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   217
    JavaTestThread(post),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   218
    _id(id),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   219
    _from(from),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   220
    _to(to),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   221
    _processed(processed),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   222
    _process_limit(process_limit),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   223
    _local_processed(0),
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   224
    _ready(false)
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   225
  {}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   226
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   227
  virtual void main_run() {
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 53410
diff changeset
   228
    Atomic::release_store_fence(&_ready, true);
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   229
    while (true) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   230
      Element* e = _from->pop();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   231
      if (e != NULL) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   232
        _to->push(*e);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   233
        Atomic::inc(_processed);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   234
        ++_local_processed;
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 53410
diff changeset
   235
      } else if (Atomic::load_acquire(_processed) == _process_limit) {
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   236
        tty->print_cr("thread %u processed " SIZE_FORMAT, _id, _local_processed);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   237
        return;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   238
      }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   239
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   240
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   241
59247
56bf71d64d51 8234562: Move OrderAccess::release_store*/load_acquire to Atomic
stefank
parents: 53410
diff changeset
   242
  bool ready() const { return Atomic::load_acquire(&_ready); }
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   243
};
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   244
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   245
TEST_VM(LockFreeStackTest, stress) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   246
  Semaphore post;
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   247
  TestStack initial_stack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   248
  TestStack start_stack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   249
  TestStack middle_stack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   250
  TestStack final_stack;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   251
  volatile size_t stage1_processed = 0;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   252
  volatile size_t stage2_processed = 0;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   253
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   254
  const size_t nelements = 10000;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   255
  Element* elements = NEW_C_HEAP_ARRAY(Element, nelements, mtOther);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   256
  for (size_t id = 0; id < nelements; ++id) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   257
    ::new (&elements[id]) Element(id);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   258
    initial_stack.push(elements[id]);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   259
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   260
  ASSERT_EQ(nelements, initial_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   261
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   262
  // - stage1 threads pop from start_stack and push to middle_stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   263
  // - stage2 threads pop from middle_stack and push to final_stack.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   264
  // - all threads in a stage count the number of elements processed in
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   265
  //   their corresponding stageN_processed counter.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   266
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   267
  const uint stage1_threads = 2;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   268
  const uint stage2_threads = 2;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   269
  const uint nthreads = stage1_threads + stage2_threads;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   270
  LockFreeStackTestThread* threads[nthreads] = {};
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   271
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   272
  for (uint i = 0; i < ARRAY_SIZE(threads); ++i) {
53410
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   273
    TestStack* from = &start_stack;
571f12d51db5 8217423: Windows gtest build fails after JDK-8212826 (Make PtrQueue free list lock-free)
shade
parents: 53404
diff changeset
   274
    TestStack* to = &middle_stack;
53404
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   275
    volatile size_t* processed = &stage1_processed;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   276
    if (i >= stage1_threads) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   277
      from = &middle_stack;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   278
      to = &final_stack;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   279
      processed = &stage2_processed;
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   280
    }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   281
    threads[i] =
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   282
      new LockFreeStackTestThread(&post, i, from, to, processed, nelements);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   283
    threads[i]->doit();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   284
    while (!threads[i]->ready()) {} // Wait until ready to start test.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   285
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   286
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   287
  // Transfer elements to start_stack to start test.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   288
  start_stack.prepend(*initial_stack.pop_all());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   289
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   290
  // Wait for all threads to complete.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   291
  for (uint i = 0; i < nthreads; ++i) {
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   292
    post.wait();
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   293
  }
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   294
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   295
  // Verify expected state.
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   296
  ASSERT_EQ(nelements, stage1_processed);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   297
  ASSERT_EQ(nelements, stage2_processed);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   298
  ASSERT_EQ(0u, initial_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   299
  ASSERT_EQ(0u, start_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   300
  ASSERT_EQ(0u, middle_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   301
  ASSERT_EQ(nelements, final_stack.length());
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   302
  while (final_stack.pop() != NULL) {}
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   303
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   304
  FREE_C_HEAP_ARRAY(Element, elements);
9ff1e6cacac3 8212826: Make PtrQueue free list lock-free
kbarrett
parents:
diff changeset
   305
}