22 */ |
22 */ |
23 |
23 |
24 #include "precompiled.hpp" |
24 #include "precompiled.hpp" |
25 #include "gc/z/zGlobals.hpp" |
25 #include "gc/z/zGlobals.hpp" |
26 #include "gc/z/zTask.hpp" |
26 #include "gc/z/zTask.hpp" |
|
27 #include "gc/z/zThread.hpp" |
27 #include "gc/z/zWorkers.inline.hpp" |
28 #include "gc/z/zWorkers.inline.hpp" |
28 #include "runtime/os.hpp" |
29 #include "runtime/os.hpp" |
29 #include "runtime/mutexLocker.hpp" |
30 #include "runtime/mutexLocker.hpp" |
30 #include "runtime/safepoint.hpp" |
31 #include "runtime/safepoint.hpp" |
31 |
32 |
62 // we then risk being out-run by the application. Using 12.5% of the active |
63 // we then risk being out-run by the application. Using 12.5% of the active |
63 // processors appears to be a fairly good balance. |
64 // processors appears to be a fairly good balance. |
64 return calculate_nworkers(12.5); |
65 return calculate_nworkers(12.5); |
65 } |
66 } |
66 |
67 |
67 class ZWorkersWarmupTask : public ZTask { |
68 class ZWorkersInitializeTask : public ZTask { |
68 private: |
69 private: |
69 const uint _nworkers; |
70 const uint _nworkers; |
70 uint _started; |
71 uint _started; |
71 Monitor _monitor; |
72 Monitor _monitor; |
72 |
73 |
73 public: |
74 public: |
74 ZWorkersWarmupTask(uint nworkers) : |
75 ZWorkersInitializeTask(uint nworkers) : |
75 ZTask("ZWorkersWarmupTask"), |
76 ZTask("ZWorkersInitializeTask"), |
76 _nworkers(nworkers), |
77 _nworkers(nworkers), |
77 _started(0), |
78 _started(0), |
78 _monitor(Monitor::leaf, "ZWorkersWarmup", false, Monitor::_safepoint_check_never) {} |
79 _monitor(Monitor::leaf, |
|
80 "ZWorkersInitialize", |
|
81 false /* allow_vm_block */, |
|
82 Monitor::_safepoint_check_never) {} |
79 |
83 |
80 virtual void work() { |
84 virtual void work() { |
|
85 // Register as worker |
|
86 ZThread::set_worker(); |
|
87 |
81 // Wait for all threads to start |
88 // Wait for all threads to start |
82 MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag); |
89 MonitorLockerEx ml(&_monitor, Monitor::_no_safepoint_check_flag); |
83 if (++_started == _nworkers) { |
90 if (++_started == _nworkers) { |
84 // All threads started |
91 // All threads started |
85 ml.notify_all(); |
92 ml.notify_all(); |
105 _workers.update_active_workers(nworkers()); |
112 _workers.update_active_workers(nworkers()); |
106 if (_workers.active_workers() != nworkers()) { |
113 if (_workers.active_workers() != nworkers()) { |
107 vm_exit_during_initialization("Failed to create ZWorkers"); |
114 vm_exit_during_initialization("Failed to create ZWorkers"); |
108 } |
115 } |
109 |
116 |
110 // Warm up worker threads by having them execute a dummy task. |
117 // Execute task to register threads as workers. This also helps |
111 // This helps reduce latency in early GC pauses, which otherwise |
118 // reduce latency in early GC pauses, which otherwise would have |
112 // would have to take on any warmup costs. |
119 // to take on any warmup costs. |
113 ZWorkersWarmupTask task(nworkers()); |
120 ZWorkersInitializeTask task(nworkers()); |
114 run(&task, nworkers()); |
121 run(&task, nworkers()); |
115 } |
122 } |
116 |
123 |
117 void ZWorkers::set_boost(bool boost) { |
124 void ZWorkers::set_boost(bool boost) { |
118 if (boost) { |
125 if (boost) { |