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/g1FreeIdSet.hpp"
27 #include "memory/allocation.hpp"
28 #include "runtime/atomic.hpp"
29 #include "runtime/interfaceSupport.inline.hpp"
30 #include "runtime/orderAccess.hpp"
31 #include "runtime/semaphore.inline.hpp"
32 #include "runtime/thread.hpp"
33 #include "utilities/debug.hpp"
34 #include "utilities/globalDefinitions.hpp"
35 #include "utilities/ostream.hpp"
36 #include "threadHelper.inline.hpp"
37 #include "unittest.hpp"
38
39 struct G1FreeIdSet::TestSupport : AllStatic {
40 static uint next(const G1FreeIdSet& set, uint index) {
41 assert(index < set._size, "precondition");
42 return set._next[index];
43 }
44
45 static uint start(const G1FreeIdSet& set) { return set._start; }
46 static uint size(const G1FreeIdSet& set) { return set._size; }
47 static uintx mask(const G1FreeIdSet& set) { return set._head_index_mask; }
48 static uintx head(const G1FreeIdSet& set) { return Atomic::load(&set._head); }
49
50 static uint head_index(const G1FreeIdSet& set, uintx head) {
91 volatile size_t* _total_allocations;
92 volatile bool* _continue_running;
93 size_t _allocations;
94 uint _thread_number;
95
96 public:
97 TestG1FreeIdSetThread(uint thread_number,
98 Semaphore* post,
99 G1FreeIdSet* set,
100 volatile size_t* total_allocations,
101 volatile bool* continue_running) :
102 JavaTestThread(post),
103 _set(set),
104 _total_allocations(total_allocations),
105 _continue_running(continue_running),
106 _allocations(0),
107 _thread_number(thread_number)
108 {}
109
110 virtual void main_run() {
111 while (OrderAccess::load_acquire(_continue_running)) {
112 uint id = _set->claim_par_id();
113 _set->release_par_id(id);
114 ++_allocations;
115 ThreadBlockInVM tbiv(this); // Safepoint check.
116 }
117 tty->print_cr("%u allocations: " SIZE_FORMAT, _thread_number, _allocations);
118 Atomic::add(_allocations, _total_allocations);
119 }
120 };
121
122 TEST_VM(G1FreeIdSetTest, stress) {
123 const uint start = 5;
124 const uint size = 3;
125 const uint nthreads = size + 1;
126 const uint milliseconds_to_run = 1000;
127
128 Semaphore post;
129 volatile size_t total_allocations = 0;
130 volatile bool continue_running = true;
131
132 G1FreeIdSet set(start, size);
133
134 TestG1FreeIdSetThread* threads[nthreads] = {};
135 for (uint i = 0; i < nthreads; ++i) {
136 threads[i] = new TestG1FreeIdSetThread(i,
137 &post,
138 &set,
139 &total_allocations,
140 &continue_running);
141 threads[i]->doit();
142 }
143
144 JavaThread* this_thread = JavaThread::current();
145 tty->print_cr("Stressing G1FreeIdSet for %u ms", milliseconds_to_run);
146 {
147 ThreadInVMfromNative invm(this_thread);
148 this_thread->sleep(milliseconds_to_run);
149 }
150 OrderAccess::release_store(&continue_running, false);
151 for (uint i = 0; i < nthreads; ++i) {
152 ThreadInVMfromNative invm(this_thread);
153 post.wait_with_safepoint_check(this_thread);
154 }
155 tty->print_cr("total allocations: " SIZE_FORMAT, total_allocations);
156 tty->print_cr("final free list: ");
157 uint ids[size] = {};
158 for (uint i = 0; i < size; ++i) {
159 uint id = set.claim_par_id();
160 uint index = id - TestSupport::start(set);
161 ASSERT_LT(index, TestSupport::size(set));
162 tty->print_cr(" %u: %u", i, index);
163 }
164 ASSERT_EQ(size, TestSupport::head_index(set, TestSupport::head(set)));
165 }
|
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/g1FreeIdSet.hpp"
27 #include "memory/allocation.hpp"
28 #include "runtime/atomic.hpp"
29 #include "runtime/interfaceSupport.inline.hpp"
30 #include "runtime/semaphore.inline.hpp"
31 #include "runtime/thread.hpp"
32 #include "utilities/debug.hpp"
33 #include "utilities/globalDefinitions.hpp"
34 #include "utilities/ostream.hpp"
35 #include "threadHelper.inline.hpp"
36 #include "unittest.hpp"
37
38 struct G1FreeIdSet::TestSupport : AllStatic {
39 static uint next(const G1FreeIdSet& set, uint index) {
40 assert(index < set._size, "precondition");
41 return set._next[index];
42 }
43
44 static uint start(const G1FreeIdSet& set) { return set._start; }
45 static uint size(const G1FreeIdSet& set) { return set._size; }
46 static uintx mask(const G1FreeIdSet& set) { return set._head_index_mask; }
47 static uintx head(const G1FreeIdSet& set) { return Atomic::load(&set._head); }
48
49 static uint head_index(const G1FreeIdSet& set, uintx head) {
90 volatile size_t* _total_allocations;
91 volatile bool* _continue_running;
92 size_t _allocations;
93 uint _thread_number;
94
95 public:
96 TestG1FreeIdSetThread(uint thread_number,
97 Semaphore* post,
98 G1FreeIdSet* set,
99 volatile size_t* total_allocations,
100 volatile bool* continue_running) :
101 JavaTestThread(post),
102 _set(set),
103 _total_allocations(total_allocations),
104 _continue_running(continue_running),
105 _allocations(0),
106 _thread_number(thread_number)
107 {}
108
109 virtual void main_run() {
110 while (Atomic::load_acquire(_continue_running)) {
111 uint id = _set->claim_par_id();
112 _set->release_par_id(id);
113 ++_allocations;
114 ThreadBlockInVM tbiv(this); // Safepoint check.
115 }
116 tty->print_cr("%u allocations: " SIZE_FORMAT, _thread_number, _allocations);
117 Atomic::add(_allocations, _total_allocations);
118 }
119 };
120
121 TEST_VM(G1FreeIdSetTest, stress) {
122 const uint start = 5;
123 const uint size = 3;
124 const uint nthreads = size + 1;
125 const uint milliseconds_to_run = 1000;
126
127 Semaphore post;
128 volatile size_t total_allocations = 0;
129 volatile bool continue_running = true;
130
131 G1FreeIdSet set(start, size);
132
133 TestG1FreeIdSetThread* threads[nthreads] = {};
134 for (uint i = 0; i < nthreads; ++i) {
135 threads[i] = new TestG1FreeIdSetThread(i,
136 &post,
137 &set,
138 &total_allocations,
139 &continue_running);
140 threads[i]->doit();
141 }
142
143 JavaThread* this_thread = JavaThread::current();
144 tty->print_cr("Stressing G1FreeIdSet for %u ms", milliseconds_to_run);
145 {
146 ThreadInVMfromNative invm(this_thread);
147 this_thread->sleep(milliseconds_to_run);
148 }
149 Atomic::release_store(&continue_running, false);
150 for (uint i = 0; i < nthreads; ++i) {
151 ThreadInVMfromNative invm(this_thread);
152 post.wait_with_safepoint_check(this_thread);
153 }
154 tty->print_cr("total allocations: " SIZE_FORMAT, total_allocations);
155 tty->print_cr("final free list: ");
156 uint ids[size] = {};
157 for (uint i = 0; i < size; ++i) {
158 uint id = set.claim_par_id();
159 uint index = id - TestSupport::start(set);
160 ASSERT_LT(index, TestSupport::size(set));
161 tty->print_cr(" %u: %u", i, index);
162 }
163 ASSERT_EQ(size, TestSupport::head_index(set, TestSupport::head(set)));
164 }
|