2
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
25
#include "precompiled.hpp"
26
#include "runtime/atomic.hpp"
27
#include "runtime/interfaceSupport.inline.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"
38
class SingleWriterSynchronizerTestReader : public JavaTestThread {
39
SingleWriterSynchronizer* _synchronizer;
40
volatile uintx* _synchronized_value;
41
volatile int* _continue_running;
43
static const uint reader_iterations = 10;
46
SingleWriterSynchronizerTestReader(Semaphore* post,
47
SingleWriterSynchronizer* synchronizer,
48
volatile uintx* synchronized_value,
49
volatile int* continue_running) :
51
_synchronizer(synchronizer),
52
_synchronized_value(synchronized_value),
53
_continue_running(continue_running)
56
virtual void main_run() {
57
size_t iterations = 0;
58
size_t values_changed = 0;
59
while (Atomic::load_acquire(_continue_running) != 0) {
60
{ ThreadBlockInVM tbiv(this); } // Safepoint check outside critical section.
62
SingleWriterSynchronizer::CriticalSection cs(_synchronizer);
63
uintx value = Atomic::load_acquire(_synchronized_value);
64
uintx new_value = value;
65
for (uint i = 0; i < reader_iterations; ++i) {
66
new_value = Atomic::load_acquire(_synchronized_value);
67
// A reader can see either the value it first read after
68
// entering the critical section, or that value + 1. No other
69
// values are possible.
70
if (value != new_value) {
71
ASSERT_EQ((value + 1), new_value);
74
if (value != new_value) {
78
tty->print_cr("reader iterations: " SIZE_FORMAT ", changes: " SIZE_FORMAT,
79
iterations, values_changed);
83
class SingleWriterSynchronizerTestWriter : public JavaTestThread {
84
SingleWriterSynchronizer* _synchronizer;
85
volatile uintx* _synchronized_value;
86
volatile int* _continue_running;
89
SingleWriterSynchronizerTestWriter(Semaphore* post,
90
SingleWriterSynchronizer* synchronizer,
91
volatile uintx* synchronized_value,
92
volatile int* continue_running) :
94
_synchronizer(synchronizer),
95
_synchronized_value(synchronized_value),
96
_continue_running(continue_running)
99
virtual void main_run() {
100
while (Atomic::load_acquire(_continue_running) != 0) {
101
++*_synchronized_value;
102
_synchronizer->synchronize();
103
{ ThreadBlockInVM tbiv(this); } // Safepoint check.
105
tty->print_cr("writer iterations: " UINTX_FORMAT, *_synchronized_value);
109
const uint nreaders = 5;
110
const uint milliseconds_to_run = 1000;
112
TEST_VM(TestSingleWriterSynchronizer, stress) {
114
SingleWriterSynchronizer synchronizer;
115
volatile uintx synchronized_value = 0;
116
volatile int continue_running = 1;
118
JavaTestThread* readers[nreaders] = {};
119
for (uint i = 0; i < nreaders; ++i) {
120
readers[i] = new SingleWriterSynchronizerTestReader(&post,
127
JavaTestThread* writer =
128
new SingleWriterSynchronizerTestWriter(&post,
135
tty->print_cr("Stressing synchronizer for %u ms", milliseconds_to_run);
136
JavaThread* cur = JavaThread::current();
138
ThreadInVMfromNative invm(cur);
139
cur->sleep(milliseconds_to_run);
141
continue_running = 0;
142
for (uint i = 0; i < nreaders + 1; ++i) {