test/hotspot/gtest/utilities/test_globalCounter.cpp
changeset 49800 69d7398038c5
child 49831 81e8cdf31b5a
equal deleted inserted replaced
49799:33dcb9c42f55 49800:69d7398038c5
       
     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.inline.hpp"
       
    27 #include "runtime/os.hpp"
       
    28 #include "utilities/globalCounter.hpp"
       
    29 #include "utilities/globalCounter.inline.hpp"
       
    30 #include "utilitiesHelper.inline.hpp"
       
    31 
       
    32 #define GOOD 1337
       
    33 #define BAD  4711
       
    34 
       
    35 struct TestData {
       
    36   long test_value;
       
    37 };
       
    38 
       
    39 class RCUReaderThread : public JavaTestThread {
       
    40 public:
       
    41   static volatile bool _exit;
       
    42   volatile TestData** _test;
       
    43   Semaphore* _wrt_start;
       
    44   RCUReaderThread(Semaphore* post, volatile TestData** test, Semaphore* wrt_start)
       
    45     : JavaTestThread(post), _test(test), _wrt_start(wrt_start) {};
       
    46   virtual ~RCUReaderThread(){}
       
    47   void main_run() {
       
    48     _wrt_start->signal();
       
    49     while (!_exit) {
       
    50       GlobalCounter::critical_section_begin(this);
       
    51       volatile TestData* test = OrderAccess::load_acquire(_test);
       
    52       long value = OrderAccess::load_acquire(&test->test_value);
       
    53       ASSERT_EQ(value, GOOD);
       
    54       GlobalCounter::critical_section_end(this);
       
    55       {
       
    56         GlobalCounter::CriticalSection cs(this);
       
    57         volatile TestData* test = OrderAccess::load_acquire(_test);
       
    58         long value = OrderAccess::load_acquire(&test->test_value);
       
    59         ASSERT_EQ(value, GOOD);
       
    60       }
       
    61     }
       
    62   }
       
    63 };
       
    64 
       
    65 volatile bool RCUReaderThread::_exit = false;
       
    66 
       
    67 class RCUWriterThread : public JavaTestThread {
       
    68 public:
       
    69   RCUWriterThread(Semaphore* post) : JavaTestThread(post) {
       
    70   };
       
    71   virtual ~RCUWriterThread(){}
       
    72   void main_run() {
       
    73     static const int NUMBER_OF_READERS = 4;
       
    74     Semaphore post;
       
    75     Semaphore wrt_start;
       
    76     volatile TestData* test = NULL;
       
    77 
       
    78     RCUReaderThread* reader1 = new RCUReaderThread(&post, &test, &wrt_start);
       
    79     RCUReaderThread* reader2 = new RCUReaderThread(&post, &test, &wrt_start);
       
    80     RCUReaderThread* reader3 = new RCUReaderThread(&post, &test, &wrt_start);
       
    81     RCUReaderThread* reader4 = new RCUReaderThread(&post, &test, &wrt_start);
       
    82 
       
    83     TestData* tmp = new TestData();
       
    84     tmp->test_value = GOOD;
       
    85     OrderAccess::release_store_fence(&test, tmp);
       
    86 
       
    87     reader1->doit();
       
    88     reader2->doit();
       
    89     reader3->doit();
       
    90     reader4->doit();
       
    91 
       
    92     int nw = NUMBER_OF_READERS;
       
    93     while (nw > 0) {
       
    94       wrt_start.wait();
       
    95       --nw;
       
    96     }
       
    97     jlong stop_ms = os::javaTimeMillis() + 1000; // 1 seconds max test time
       
    98     for (int i = 0; i < 100000 && stop_ms > os::javaTimeMillis(); i++) {
       
    99       volatile TestData* free_tmp = test;
       
   100       tmp = new TestData();
       
   101       tmp->test_value = GOOD;
       
   102       OrderAccess::release_store(&test, tmp);
       
   103       GlobalCounter::write_synchronize();
       
   104       free_tmp->test_value = BAD;
       
   105       delete free_tmp;
       
   106     }
       
   107     RCUReaderThread::_exit = true;
       
   108     for (int i = 0; i < NUMBER_OF_READERS; i++) {
       
   109       post.wait();
       
   110     }
       
   111   }
       
   112 };
       
   113 
       
   114 TEST_VM(GlobalCounter, critical_section) {
       
   115   RCUReaderThread::_exit = false;
       
   116   mt_test_doer<RCUWriterThread>();
       
   117 }