1 /*
2 * Copyright (c) 2018, 2019, Red Hat, Inc. 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 #ifndef SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
25 #define SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
26
27 #include "gc/shared/taskqueue.hpp"
28 #include "runtime/mutex.hpp"
29 #include "runtime/thread.hpp"
30
31 /*
32 * OWST stands for Optimized Work Stealing Threads
33 *
34 * This is an enhanced implementation of Google's work stealing
35 * protocol, which is described in the paper:
36 * "Wessam Hassanein. 2016. Understanding and improving JVM GC work
37 * stealing at the data center scale. In Proceedings of the 2016 ACM
38 * SIGPLAN International Symposium on Memory Management (ISMM 2016). ACM,
39 * New York, NY, USA, 46-54. DOI: https://doi.org/10.1145/2926697.2926706"
40 *
41 * Instead of a dedicated spin-master, our implementation will let spin-master relinquish
42 * the role before it goes to sleep/wait, allowing newly arrived threads to compete for the role.
43 * The intention of above enhancement is to reduce spin-master's latency on detecting new tasks
44 * for stealing and termination condition.
45 */
46
47 class OWSTTaskTerminator: public ParallelTaskTerminator {
48 private:
49 Monitor* _blocker;
50 Thread* _spin_master;
51
52 public:
53 OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set) :
54 ParallelTaskTerminator(n_threads, queue_set), _spin_master(NULL) {
55 _blocker = new Monitor(Mutex::leaf, "OWSTTaskTerminator", false, Monitor::_safepoint_check_never);
56 }
57
58 virtual ~OWSTTaskTerminator() {
59 assert(_spin_master == NULL, "Should have been reset");
60 assert(_blocker != NULL, "Can not be NULL");
61 delete _blocker;
62 }
63
64 bool offer_termination(TerminatorTerminator* terminator);
65
66 protected:
67 // If should exit current termination protocol
68 virtual bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
69
70 private:
71 size_t tasks_in_queue_set() { return _queue_set->tasks(); }
72
73 /*
74 * Perform spin-master task.
75 * Return true if termination condition is detected, otherwise return false
76 */
77 bool do_spin_master_work(TerminatorTerminator* terminator);
78 };
79
80
81 #endif // SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
|
1 /*
2 * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
3 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25 #ifndef SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
26 #define SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
27
28 #include "memory/allocation.hpp"
29 #include "runtime/mutex.hpp"
30 #include "runtime/thread.hpp"
31
32 // Define this to enable additional tracing probes.
33 #undef TRACESPINNING
34
35 class TaskQueueSetSuper;
36 class TerminatorTerminator;
37
38 /*
39 * Provides a task termination protocol. OWST stands for Optimized Work Stealing Threads
40 *
41 * This is an enhanced implementation of Google's work stealing task termination
42 * protocol, which is described in the paper:
43 * "Wessam Hassanein. 2016. Understanding and improving JVM GC work
44 * stealing at the data center scale. In Proceedings of the 2016 ACM
45 * SIGPLAN International Symposium on Memory Management (ISMM 2016). ACM,
46 * New York, NY, USA, 46-54. DOI: https://doi.org/10.1145/2926697.2926706"
47 *
48 * Instead of a dedicated spin-master, our implementation will let spin-master relinquish
49 * the role before it goes to sleep/wait, allowing newly arrived threads to compete for the role.
50 * The intention of above enhancement is to reduce spin-master's latency on detecting new tasks
51 * for stealing and termination condition.
52 */
53 class OWSTTaskTerminator : public CHeapObj<mtGC> {
54 uint _n_threads;
55 TaskQueueSetSuper* _queue_set;
56
57 DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0);
58 volatile uint _offered_termination;
59 DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile uint));
60
61 #ifdef ASSERT
62 bool peek_in_queue_set();
63 #endif
64 void yield();
65
66 Monitor* _blocker;
67 Thread* _spin_master;
68
69 #ifdef TRACESPINNING
70 static uint _total_yields;
71 static uint _total_spins;
72 static uint _total_peeks;
73 #endif
74
75 // If we should exit current termination protocol
76 bool exit_termination(size_t tasks, TerminatorTerminator* terminator);
77
78 size_t tasks_in_queue_set() const;
79
80 // Perform spin-master task.
81 // Return true if termination condition is detected, otherwise return false
82 bool do_spin_master_work(TerminatorTerminator* terminator);
83
84 NONCOPYABLE(OWSTTaskTerminator);
85
86 public:
87 OWSTTaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
88 ~OWSTTaskTerminator();
89
90 // The current thread has no work, and is ready to terminate if everyone
91 // else is. If returns "true", all threads are terminated. If returns
92 // "false", available work has been observed in one of the task queues,
93 // so the global task is not complete.
94 bool offer_termination() {
95 return offer_termination(NULL);
96 }
97
98 // As above, but it also terminates if the should_exit_termination()
99 // method of the terminator parameter returns true. If terminator is
100 // NULL, then it is ignored.
101 bool offer_termination(TerminatorTerminator* terminator);
102
103 // Reset the terminator, so that it may be reused again.
104 // The caller is responsible for ensuring that this is done
105 // in an MT-safe manner, once the previous round of use of
106 // the terminator is finished.
107 void reset_for_reuse();
108 // Same as above but the number of parallel threads is set to the
109 // given number.
110 void reset_for_reuse(uint n_threads);
111
112 #ifdef TRACESPINNING
113 static uint total_yields() { return _total_yields; }
114 static uint total_spins() { return _total_spins; }
115 static uint total_peeks() { return _total_peeks; }
116 static void print_termination_counts();
117 #endif
118 };
119
120
121 #endif // SHARE_GC_SHARED_OWSTTASKTERMINATOR_HPP
|