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); | 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/os.hpp" 28 #include "utilities/globalCounter.hpp" 29 #include "utilities/globalCounter.inline.hpp" 30 #include "utilities/spinYield.hpp" 31 #include "threadHelper.inline.hpp" 32 33 enum NestedTestState { 34 START, 35 START_WAIT, 36 OUTER_ENTERED, 37 INNER_ENTERED, 38 INNER_EXITED, 39 OUTER_EXITED, 40 SYNCHRONIZING, 41 SYNCHRONIZED 42 }; 43 template<> struct IsRegisteredEnum<NestedTestState> : public TrueType {}; 44 45 class RCUNestedThread : public JavaTestThread { 46 volatile NestedTestState _state; 47 volatile bool _proceed; 48 49 protected: 50 RCUNestedThread(Semaphore* post) : 51 JavaTestThread(post), 52 _state(START), 53 _proceed(false) 54 {} 55 56 ~RCUNestedThread() {} 57 58 void set_state(NestedTestState new_state) { 59 Atomic::release_store(&_state, new_state); 60 } 61 62 void wait_with_state(NestedTestState new_state) { 63 SpinYield spinner; 64 Atomic::release_store(&_state, new_state); 65 while (!Atomic::load_acquire(&_proceed)) { 66 spinner.wait(); 67 } 68 Atomic::release_store(&_proceed, false); 69 } 70 71 public: 72 NestedTestState state() const { 73 return Atomic::load_acquire(&_state); 74 } 75 76 void wait_for_state(NestedTestState goal) { 77 SpinYield spinner; 78 while (state() != goal) { 79 spinner.wait(); 80 } 81 } 82 83 void proceed() { 84 Atomic::release_store(&_proceed, true); 85 } 86 }; 87 88 class RCUNestedReaderThread : public RCUNestedThread { 89 public: 90 RCUNestedReaderThread(Semaphore* post) : 91 RCUNestedThread(post) 92 {} 93 94 virtual void main_run(); 95 }; 96 97 void RCUNestedReaderThread::main_run() { 98 wait_with_state(START_WAIT); 99 { 100 GlobalCounter::CriticalSection outer(Thread::current()); 101 wait_with_state(OUTER_ENTERED); 102 { 103 GlobalCounter::CriticalSection inner(Thread::current()); 104 wait_with_state(INNER_ENTERED); |