jdk

Форк
0
/
test_g1ServiceThread.cpp 
184 строки · 5.2 Кб
1
/*
2
 * Copyright (c) 2021, 2022, 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 "gc/g1/g1ServiceThread.hpp"
27
#include "runtime/interfaceSupport.inline.hpp"
28
#include "runtime/os.hpp"
29
#include "utilities/autoRestore.hpp"
30
#include "unittest.hpp"
31

32
class CheckTask : public G1ServiceTask {
33
  int _execution_count;
34
  bool _reschedule;
35

36
public:
37
  CheckTask(const char* name) :
38
      G1ServiceTask(name),
39
      _execution_count(0),
40
      _reschedule(true) { }
41
  virtual void execute() {
42
    _execution_count++;
43
    if (_reschedule) {
44
      schedule(100);
45
    }
46
  }
47

48
  int execution_count() { return _execution_count;}
49
  void set_reschedule(bool reschedule) { _reschedule = reschedule; }
50
};
51

52
static void stop_service_thread(G1ServiceThread* thread) {
53
  ThreadInVMfromNative tvn(JavaThread::current());
54
  thread->stop();
55
}
56

57
// Test that a task that is added during runtime gets run.
58
TEST_VM(G1ServiceThread, test_add) {
59
  // Create thread and let it start.
60
  G1ServiceThread* st = new G1ServiceThread();
61
  os::naked_short_sleep(500);
62

63
  CheckTask ct("AddAndRun");
64
  st->register_task(&ct);
65

66
  // Give CheckTask time to run.
67
  os::naked_short_sleep(500);
68
  stop_service_thread(st);
69

70
  ASSERT_GT(ct.execution_count(), 0);
71
}
72

73
// Test that a task that is added while the service thread is
74
// waiting gets run in a timely manner.
75
TEST_VM(G1ServiceThread, test_add_while_waiting) {
76
  // Make sure default tasks use long intervals so that the service thread
77
  // is doing a long wait for the next execution.
78
  AutoModifyRestore<uintx> f1(G1PeriodicGCInterval, 100000);
79

80
  // Create thread and let it start.
81
  G1ServiceThread* st = new G1ServiceThread();
82
  os::naked_short_sleep(500);
83

84
  // Register a new task that should run right away.
85
  CheckTask ct("AddWhileWaiting");
86
  st->register_task(&ct);
87

88
  // Give CheckTask time to run.
89
  os::naked_short_sleep(500);
90
  stop_service_thread(st);
91

92
  ASSERT_GT(ct.execution_count(), 0);
93
}
94

95
// Test that a task with negative timeout is not rescheduled.
96
TEST_VM(G1ServiceThread, test_add_run_once) {
97
  // Create thread and let it start.
98
  G1ServiceThread* st = new G1ServiceThread();
99
  os::naked_short_sleep(500);
100

101
  // Set reschedule to false to only run once.
102
  CheckTask ct("AddRunOnce");
103
  ct.set_reschedule(false);
104
  st->register_task(&ct);
105

106
  // Give CheckTask time to run.
107
  os::naked_short_sleep(500);
108
  stop_service_thread(st);
109

110
  // Should be exactly 1 since negative timeout should
111
  // prevent rescheduling.
112
  ASSERT_EQ(ct.execution_count(), 1);
113
}
114

115
class TestTask : public G1ServiceTask {
116
  jlong _delay_ms;
117
public:
118
  TestTask(jlong delay) :
119
      G1ServiceTask("TestTask"),
120
      _delay_ms(delay) {
121
    set_time(delay);
122
  }
123
  virtual void execute() {}
124
  void update_time(jlong now, int multiplier) {
125
    set_time(now + (_delay_ms * multiplier));
126
  }
127
};
128

129
TEST_VM(G1ServiceTaskQueue, add_ordered) {
130
  G1ServiceTaskQueue queue;
131

132
  int num_test_tasks = 5;
133
  for (int i = 1; i <= num_test_tasks; i++) {
134
    // Create tasks with different timeout.
135
    TestTask* task = new TestTask(100 * i);
136
    queue.add_ordered(task);
137
  }
138

139
  // Now fake a run-loop, that reschedules the tasks using a
140
  // random multiplier.
141
  for (jlong now = 0; now < 1000000; now++) {
142
    // Random multiplier is at least 1 to ensure progress.
143
    int multiplier = 1 + os::random() % 10;
144
    while (queue.front()->time() < now) {
145
      TestTask* task = (TestTask*) queue.front();
146
      queue.remove_front();
147
      // Update delay multiplier.
148
      task->execute();
149
      task->update_time(now, multiplier);
150
      // All additions will verify that the queue is sorted.
151
      queue.add_ordered(task);
152
    }
153
  }
154

155
  while (!queue.is_empty()) {
156
    G1ServiceTask* task = queue.front();
157
    queue.remove_front();
158
    delete task;
159
  }
160
}
161

162
#ifdef ASSERT
163
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, remove_from_empty,
164
    ".*Should never try to verify empty queue") {
165
  G1ServiceTaskQueue queue;
166
  queue.remove_front();
167
}
168

169
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, get_from_empty,
170
    ".*Should never try to verify empty queue") {
171
  G1ServiceTaskQueue queue;
172
  queue.front();
173
}
174

175
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, set_time_in_queue,
176
    ".*Not allowed to update time while in queue") {
177
  G1ServiceTaskQueue queue;
178
  TestTask a(100);
179
  queue.add_ordered(&a);
180
  // Not allowed to update time while in queue.
181
  a.update_time(500, 1);
182
}
183

184
#endif
185

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.