test/hotspot/gtest/utilities/test_singleWriterSynchronizer.cpp
changeset 51511 eb8d5aeabab3
child 51690 b83571bbc147
equal deleted inserted replaced
51510:6b0012622443 51511:eb8d5aeabab3
       
     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 
       
    25 #include "precompiled.hpp"
       
    26 #include "runtime/interfaceSupport.inline.hpp"
       
    27 #include "runtime/orderAccess.hpp"
       
    28 #include "runtime/os.hpp"
       
    29 #include "runtime/thread.hpp"
       
    30 #include "utilities/debug.hpp"
       
    31 #include "utilities/globalCounter.inline.hpp"
       
    32 #include "utilities/globalDefinitions.hpp"
       
    33 #include "utilities/ostream.hpp"
       
    34 #include "utilities/singleWriterSynchronizer.hpp"
       
    35 #include "threadHelper.inline.hpp"
       
    36 #include "unittest.hpp"
       
    37 
       
    38 class SingleWriterSynchronizerTestReader : public JavaTestThread {
       
    39   SingleWriterSynchronizer* _synchronizer;
       
    40   volatile uintx* _synchronized_value;
       
    41   volatile int* _continue_running;
       
    42 
       
    43   static const uint reader_iterations = 10;
       
    44 
       
    45 public:
       
    46   SingleWriterSynchronizerTestReader(Semaphore* post,
       
    47                                      SingleWriterSynchronizer* synchronizer,
       
    48                                      volatile uintx* synchronized_value,
       
    49                                      volatile int* continue_running) :
       
    50     JavaTestThread(post),
       
    51     _synchronizer(synchronizer),
       
    52     _synchronized_value(synchronized_value),
       
    53     _continue_running(continue_running)
       
    54   {}
       
    55 
       
    56   virtual void main_run() {
       
    57     uintx iterations = 0;
       
    58     while (OrderAccess::load_acquire(_continue_running) != 0) {
       
    59       ++iterations;
       
    60       SingleWriterSynchronizer::CriticalSection cs(_synchronizer);
       
    61       uintx value = OrderAccess::load_acquire(_synchronized_value);
       
    62       for (uint i = 0; i < reader_iterations; ++i) {
       
    63         uintx new_value = OrderAccess::load_acquire(_synchronized_value);
       
    64         // A reader can see either the value it first read after
       
    65         // entering the critical section, or that value + 1.  No other
       
    66         // values are possible.
       
    67         if (value != new_value) {
       
    68           ASSERT_EQ((value + 1), new_value);
       
    69         }
       
    70       }
       
    71     }
       
    72     tty->print_cr("reader iterations: " UINTX_FORMAT, iterations);
       
    73   }
       
    74 };
       
    75 
       
    76 class SingleWriterSynchronizerTestWriter : public JavaTestThread {
       
    77   SingleWriterSynchronizer* _synchronizer;
       
    78   volatile uintx* _synchronized_value;
       
    79   volatile int* _continue_running;
       
    80 
       
    81 public:
       
    82   SingleWriterSynchronizerTestWriter(Semaphore* post,
       
    83                                      SingleWriterSynchronizer* synchronizer,
       
    84                                      volatile uintx* synchronized_value,
       
    85                                      volatile int* continue_running) :
       
    86     JavaTestThread(post),
       
    87     _synchronizer(synchronizer),
       
    88     _synchronized_value(synchronized_value),
       
    89     _continue_running(continue_running)
       
    90   {}
       
    91 
       
    92   virtual void main_run() {
       
    93     while (OrderAccess::load_acquire(_continue_running) != 0) {
       
    94       ++*_synchronized_value;
       
    95       _synchronizer->synchronize();
       
    96     }
       
    97     tty->print_cr("writer iterations: " UINTX_FORMAT, *_synchronized_value);
       
    98   }
       
    99 };
       
   100 
       
   101 const uint nreaders = 5;
       
   102 const uint milliseconds_to_run = 3000;
       
   103 
       
   104 TEST_VM(TestSingleWriterSynchronizer, stress) {
       
   105   Semaphore post;
       
   106   SingleWriterSynchronizer synchronizer;
       
   107   volatile uintx synchronized_value = 0;
       
   108   volatile int continue_running = 1;
       
   109 
       
   110   JavaTestThread* readers[nreaders] = {};
       
   111   for (uint i = 0; i < nreaders; ++i) {
       
   112     readers[i] = new SingleWriterSynchronizerTestReader(&post,
       
   113                                                         &synchronizer,
       
   114                                                         &synchronized_value,
       
   115                                                         &continue_running);
       
   116     readers[i]->doit();
       
   117   }
       
   118 
       
   119   JavaTestThread* writer =
       
   120     new SingleWriterSynchronizerTestWriter(&post,
       
   121                                            &synchronizer,
       
   122                                            &synchronized_value,
       
   123                                            &continue_running);
       
   124 
       
   125   writer->doit();
       
   126 
       
   127   tty->print_cr("Stressing synchronizer for %u ms", milliseconds_to_run);
       
   128   {
       
   129     ThreadInVMfromNative invm(JavaThread::current());
       
   130     os::sleep(Thread::current(), milliseconds_to_run, true);
       
   131   }
       
   132   continue_running = 0;
       
   133   for (uint i = 0; i < nreaders + 1; ++i) {
       
   134     post.wait();
       
   135   }
       
   136 }