1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "metaprogramming/isRegisteredEnum.hpp" 26 #include "runtime/atomic.hpp" 27 #include "runtime/orderAccess.hpp" 28 #include "runtime/os.hpp" 29 #include "utilities/globalCounter.hpp" 30 #include "utilities/globalCounter.inline.hpp" 31 #include "utilities/spinYield.hpp" 32 #include "threadHelper.inline.hpp" 33 34 enum NestedTestState { 35 START, 36 START_WAIT, 37 OUTER_ENTERED, 38 INNER_ENTERED, 39 INNER_EXITED, 40 OUTER_EXITED, 41 SYNCHRONIZING, 42 SYNCHRONIZED 43 }; 44 template<> struct IsRegisteredEnum<NestedTestState> : public TrueType {}; 45 46 class RCUNestedThread : public JavaTestThread { 47 volatile NestedTestState _state; 48 volatile bool _proceed; 49 50 protected: 51 RCUNestedThread(Semaphore* post) : 52 JavaTestThread(post), 53 _state(START), 54 _proceed(false) 55 {} 56 57 ~RCUNestedThread() {} 58 59 void set_state(NestedTestState new_state) { 60 OrderAccess::release_store(&_state, new_state); 61 } 62 63 void wait_with_state(NestedTestState new_state) { 64 SpinYield spinner; 65 OrderAccess::release_store(&_state, new_state); 66 while (!OrderAccess::load_acquire(&_proceed)) { 67 spinner.wait(); 68 } 69 OrderAccess::release_store(&_proceed, false); 70 } 71 72 public: 73 NestedTestState state() const { 74 return OrderAccess::load_acquire(&_state); 75 } 76 77 void wait_for_state(NestedTestState goal) { 78 SpinYield spinner; 79 while (state() != goal) { 80 spinner.wait(); 81 } 82 } 83 84 void proceed() { 85 OrderAccess::release_store(&_proceed, true); 86 } 87 }; 88 89 class RCUNestedReaderThread : public RCUNestedThread { 90 public: 91 RCUNestedReaderThread(Semaphore* post) : 92 RCUNestedThread(post) 93 {} 94 95 virtual void main_run(); 96 }; 97 98 void RCUNestedReaderThread::main_run() { 99 wait_with_state(START_WAIT); 100 { 101 GlobalCounter::CriticalSection outer(Thread::current()); 102 wait_with_state(OUTER_ENTERED); 103 { 104 GlobalCounter::CriticalSection inner(Thread::current()); 105 wait_with_state(INNER_ENTERED); 106 } 107 wait_with_state(INNER_EXITED); 108 } 109 wait_with_state(OUTER_EXITED); 110 } 111 112 113 class RCUNestedWriterThread : public RCUNestedThread { 114 public: 115 RCUNestedWriterThread(Semaphore* post) : 116 RCUNestedThread(post) 117 {} 118 119 virtual void main_run(); 120 }; 121 122 void RCUNestedWriterThread::main_run() { 123 wait_with_state(START_WAIT); 124 set_state(SYNCHRONIZING); 125 GlobalCounter::write_synchronize(); 126 wait_with_state(SYNCHRONIZED); 127 } 128 129 TEST_VM(GlobalCounter, nested_critical_section) { 130 Semaphore post; 131 RCUNestedReaderThread* reader = new RCUNestedReaderThread(&post); 132 RCUNestedWriterThread* outer = new RCUNestedWriterThread(&post); 133 RCUNestedWriterThread* inner = new RCUNestedWriterThread(&post); 134 135 reader->doit(); 136 outer->doit(); 137 inner->doit(); 138 139 reader->wait_for_state(START_WAIT); 140 outer->wait_for_state(START_WAIT); 141 inner->wait_for_state(START_WAIT); 142 EXPECT_EQ(START_WAIT, reader->state()); 143 EXPECT_EQ(START_WAIT, outer->state()); 144 EXPECT_EQ(START_WAIT, inner->state()); 145 146 reader->proceed(); 147 reader->wait_for_state(OUTER_ENTERED); 148 EXPECT_EQ(OUTER_ENTERED, reader->state()); 149 EXPECT_EQ(START_WAIT, outer->state()); 150 EXPECT_EQ(START_WAIT, inner->state()); 151 152 outer->proceed(); 153 outer->wait_for_state(SYNCHRONIZING); 154 EXPECT_EQ(OUTER_ENTERED, reader->state()); 155 EXPECT_EQ(SYNCHRONIZING, outer->state()); 156 EXPECT_EQ(START_WAIT, inner->state()); 157 158 os::naked_short_sleep(100); // Give outer time in synchronization. 159 EXPECT_EQ(OUTER_ENTERED, reader->state()); 160 EXPECT_EQ(SYNCHRONIZING, outer->state()); 161 EXPECT_EQ(START_WAIT, inner->state()); 162 163 reader->proceed(); 164 reader->wait_for_state(INNER_ENTERED); 165 EXPECT_EQ(INNER_ENTERED, reader->state()); 166 EXPECT_EQ(SYNCHRONIZING, outer->state()); 167 EXPECT_EQ(START_WAIT, inner->state()); 168 169 inner->proceed(); 170 inner->wait_for_state(SYNCHRONIZING); 171 EXPECT_EQ(INNER_ENTERED, reader->state()); 172 EXPECT_EQ(SYNCHRONIZING, outer->state()); 173 EXPECT_EQ(SYNCHRONIZING, inner->state()); 174 175 os::naked_short_sleep(100); // Give writers time in synchronization. 176 EXPECT_EQ(INNER_ENTERED, reader->state()); 177 EXPECT_EQ(SYNCHRONIZING, outer->state()); 178 EXPECT_EQ(SYNCHRONIZING, inner->state()); 179 180 reader->proceed(); 181 reader->wait_for_state(INNER_EXITED); 182 // inner does *not* complete synchronization here. 183 EXPECT_EQ(INNER_EXITED, reader->state()); 184 EXPECT_EQ(SYNCHRONIZING, outer->state()); 185 EXPECT_EQ(SYNCHRONIZING, inner->state()); 186 187 os::naked_short_sleep(100); // Give writers more time in synchronization. 188 EXPECT_EQ(INNER_EXITED, reader->state()); 189 EXPECT_EQ(SYNCHRONIZING, outer->state()); 190 EXPECT_EQ(SYNCHRONIZING, inner->state()); 191 192 reader->proceed(); 193 reader->wait_for_state(OUTER_EXITED); 194 // Both inner and outer can synchronize now. 195 outer->wait_for_state(SYNCHRONIZED); 196 inner->wait_for_state(SYNCHRONIZED); 197 EXPECT_EQ(OUTER_EXITED, reader->state()); 198 EXPECT_EQ(SYNCHRONIZED, outer->state()); 199 EXPECT_EQ(SYNCHRONIZED, inner->state()); 200 201 // Wait for reader, outer, and inner to complete. 202 reader->proceed(); 203 outer->proceed(); 204 inner->proceed(); 205 for (uint i = 0; i < 3; ++i) { 206 post.wait(); 207 } 208 }