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 "runtime/atomic.hpp" 26 #include "runtime/orderAccess.hpp" 27 #include "runtime/os.hpp" 28 #include "utilities/spinYield.hpp" 29 #include "utilities/waitBarrier.hpp" 30 #include "threadHelper.inline.hpp" 31 32 static volatile int wait_tag = 1; 33 static volatile int valid_value = 0; 34 35 template <typename WaitBarrierImpl> 36 class WBThread : public JavaTestThread { 37 public: 38 static volatile bool _exit; 39 WaitBarrierType<WaitBarrierImpl>* _wait_barrier; 40 Semaphore* _wrt_start; 41 volatile int _on_barrier; 42 43 WBThread(Semaphore* post, WaitBarrierType<WaitBarrierImpl>* wb, Semaphore* wrt_start) 44 : JavaTestThread(post), _wait_barrier(wb), _wrt_start(wrt_start) {}; 45 virtual ~WBThread(){} 46 void main_run() { 47 _wrt_start->signal(); 48 int vv, tag; 49 while (!_exit) { 50 tag = OrderAccess::load_acquire(&wait_tag); 51 OrderAccess::release_store_fence(&_on_barrier, tag); 52 _wait_barrier->wait(tag); 53 vv = OrderAccess::load_acquire(&valid_value); 54 ASSERT_EQ((vv & 0x1), 0); 55 } 56 } 57 }; 58 59 template <typename WaitBarrierImpl> 60 volatile bool WBThread<WaitBarrierImpl>::_exit = false; 61 62 template <typename WaitBarrierImpl> 63 class WBArmerThread : public JavaTestThread { 64 public: 65 WBArmerThread(Semaphore* post) : JavaTestThread(post) { 66 }; 67 virtual ~WBArmerThread(){} 68 void main_run() { 69 static const int NUMBER_OF_READERS = 4; 70 Semaphore post; 71 Semaphore wrt_start; 72 WaitBarrierType<WaitBarrierImpl> wb; 73 74 wait_tag = 2; 75 76 WBThread<WaitBarrierImpl>* reader1 = new WBThread<WaitBarrierImpl>(&post, &wb, &wrt_start); 77 WBThread<WaitBarrierImpl>* reader2 = new WBThread<WaitBarrierImpl>(&post, &wb, &wrt_start); 78 WBThread<WaitBarrierImpl>* reader3 = new WBThread<WaitBarrierImpl>(&post, &wb, &wrt_start); 79 WBThread<WaitBarrierImpl>* reader4 = new WBThread<WaitBarrierImpl>(&post, &wb, &wrt_start); 80 81 reader1->doit(); 82 reader2->doit(); 83 reader3->doit(); 84 reader4->doit(); 85 86 int nw = NUMBER_OF_READERS; 87 while (nw > 0) { 88 wrt_start.wait(); 89 --nw; 90 } 91 SpinYield sp; 92 jlong stop_ms = os::javaTimeMillis() + 1000; // 1 seconds max test time 93 while (stop_ms > os::javaTimeMillis()) { 94 wb.arm(wait_tag + 1); 95 OrderAccess::release_store(&wait_tag, wait_tag + 1); 96 97 while (reader1->_on_barrier != wait_tag || 98 reader2->_on_barrier != wait_tag || 99 reader3->_on_barrier != wait_tag || 100 reader4->_on_barrier != wait_tag) { 101 sp.wait(); 102 } 103 OrderAccess::release_store(&valid_value, valid_value + 1); // odd 104 os::naked_short_sleep(1); 105 OrderAccess::release_store(&valid_value, valid_value + 1); // even 106 OrderAccess::storestore(); // Stores in WB must not float up. 107 wb.disarm(); 108 wb.wake(); 109 } 110 WBThread<WaitBarrierImpl>::_exit = true; 111 for (int i = 0; i < NUMBER_OF_READERS; i++) { 112 post.wait(); 113 } 114 } 115 }; 116 117 TEST_VM(WaitBarrier, default_wb) { 118 WBThread<WaitBarrierDefault>::_exit = false; 119 mt_test_doer<WBArmerThread<WaitBarrierDefault> >(); 120 } 121 122 #if defined(LINUX) 123 TEST_VM(WaitBarrier, generic_wb) { 124 WBThread<GenericWaitBarrier>::_exit = false; 125 mt_test_doer<WBArmerThread<GenericWaitBarrier> >(); 126 } 127 #endif