23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |
25 #ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |
26 #define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |
26 #define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |
27 |
27 |
28 #include "gc/shared/adaptiveSizePolicy.hpp" |
28 #include "logging/log.hpp" |
|
29 #include "memory/allocation.hpp" |
|
30 #include "runtime/os.inline.hpp" |
|
31 #include "runtime/thread.inline.hpp" |
|
32 #include "utilities/globalDefinitions.hpp" |
29 |
33 |
30 class WorkerManager : public AllStatic { |
34 class WorkerManager : public AllStatic { |
31 public: |
35 public: |
32 // Create additional workers as needed. |
36 // Create additional workers as needed. |
33 // active_workers - number of workers being requested for an upcoming |
37 // active_workers - number of workers being requested for an upcoming |
49 static uint add_workers (WorkerType* holder, |
53 static uint add_workers (WorkerType* holder, |
50 uint active_workers, |
54 uint active_workers, |
51 uint total_workers, |
55 uint total_workers, |
52 uint created_workers, |
56 uint created_workers, |
53 os::ThreadType worker_type, |
57 os::ThreadType worker_type, |
54 bool initializing) { |
58 bool initializing); |
55 uint start = created_workers; |
|
56 uint end = MIN2(active_workers, total_workers); |
|
57 for (uint worker_id = start; worker_id < end; worker_id += 1) { |
|
58 WorkerThread* new_worker = NULL; |
|
59 if (initializing || !InjectGCWorkerCreationFailure) { |
|
60 new_worker = holder->install_worker(worker_id); |
|
61 } |
|
62 if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) { |
|
63 log_trace(gc, task)("WorkerManager::add_workers() : " |
|
64 "creation failed due to failed allocation of native %s", |
|
65 new_worker == NULL ? "memory" : "thread"); |
|
66 if (new_worker != NULL) { |
|
67 delete new_worker; |
|
68 } |
|
69 if (initializing) { |
|
70 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources."); |
|
71 } |
|
72 break; |
|
73 } |
|
74 created_workers++; |
|
75 os::start_thread(new_worker); |
|
76 } |
|
77 |
|
78 log_trace(gc, task)("WorkerManager::add_workers() : " |
|
79 "created_workers: %u", created_workers); |
|
80 |
|
81 return created_workers; |
|
82 } |
|
83 |
59 |
84 // Log (at trace level) a change in the number of created workers. |
60 // Log (at trace level) a change in the number of created workers. |
85 template <class WorkerType> |
61 template <class WorkerType> |
86 static void log_worker_creation(WorkerType* holder, |
62 static void log_worker_creation(WorkerType* holder, |
87 uint previous_created_workers, |
63 uint previous_created_workers, |
88 uint active_workers, |
64 uint active_workers, |
89 uint created_workers, |
65 uint created_workers, |
90 bool initializing) { |
66 bool initializing); |
91 if (previous_created_workers < created_workers) { |
67 }; |
92 const char* initializing_msg = initializing ? "Adding initial" : "Creating additional"; |
68 |
93 log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u", |
69 template <class WorkerType> |
94 initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers); |
70 uint WorkerManager::add_workers(WorkerType* holder, |
|
71 uint active_workers, |
|
72 uint total_workers, |
|
73 uint created_workers, |
|
74 os::ThreadType worker_type, |
|
75 bool initializing) { |
|
76 uint start = created_workers; |
|
77 uint end = MIN2(active_workers, total_workers); |
|
78 for (uint worker_id = start; worker_id < end; worker_id += 1) { |
|
79 WorkerThread* new_worker = NULL; |
|
80 if (initializing || !InjectGCWorkerCreationFailure) { |
|
81 new_worker = holder->install_worker(worker_id); |
95 } |
82 } |
|
83 if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) { |
|
84 log_trace(gc, task)("WorkerManager::add_workers() : " |
|
85 "creation failed due to failed allocation of native %s", |
|
86 new_worker == NULL ? "memory" : "thread"); |
|
87 if (new_worker != NULL) { |
|
88 delete new_worker; |
|
89 } |
|
90 if (initializing) { |
|
91 vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources."); |
|
92 } |
|
93 break; |
|
94 } |
|
95 created_workers++; |
|
96 os::start_thread(new_worker); |
96 } |
97 } |
97 }; |
98 |
|
99 log_trace(gc, task)("WorkerManager::add_workers() : " |
|
100 "created_workers: %u", created_workers); |
|
101 |
|
102 return created_workers; |
|
103 } |
|
104 |
|
105 template <class WorkerType> |
|
106 void WorkerManager::log_worker_creation(WorkerType* holder, |
|
107 uint previous_created_workers, |
|
108 uint active_workers, |
|
109 uint created_workers, |
|
110 bool initializing) { |
|
111 if (previous_created_workers < created_workers) { |
|
112 const char* initializing_msg = initializing ? "Adding initial" : "Creating additional"; |
|
113 log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u", |
|
114 initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers); |
|
115 } |
|
116 } |
|
117 |
98 #endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |
118 #endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP |