95
96 // Waits for a task to become available to the worker.
97 // Returns when the worker has been assigned a task.
98 virtual WorkData worker_wait_for_task() = 0;
99
100 // Signal to the coordinator that the worker is done with the assigned task.
101 virtual void worker_done_with_task() = 0;
102 };
103
104 // The work gang is the collection of workers to execute tasks.
105 // The number of workers run for a task is "_active_workers"
106 // while "_total_workers" is the number of available of workers.
107 class AbstractWorkGang : public CHeapObj<mtInternal> {
108 protected:
109 // The array of worker threads for this gang.
110 AbstractGangWorker** _workers;
111 // The count of the number of workers in the gang.
112 uint _total_workers;
113 // The currently active workers in this gang.
114 uint _active_workers;
115 // Printing support.
116 const char* _name;
117
118 private:
119 // Initialize only instance data.
120 const bool _are_GC_task_threads;
121 const bool _are_ConcurrentGC_threads;
122
123 public:
124 AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
125 _name(name),
126 _total_workers(workers),
127 _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
128 _are_GC_task_threads(are_GC_task_threads),
129 _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
130 { }
131
132 // Initialize workers in the gang. Return true if initialization succeeded.
133 bool initialize_workers();
134
135 bool are_GC_task_threads() const { return _are_GC_task_threads; }
136 bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
137
138 uint total_workers() const { return _total_workers; }
139
140 virtual uint active_workers() const {
141 assert(_active_workers <= _total_workers,
142 "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
143 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
144 "Unless dynamic should use total workers");
145 return _active_workers;
146 }
147 void set_active_workers(uint v) {
148 assert(v <= _total_workers,
149 "Trying to set more workers active than there are");
150 _active_workers = MIN2(v, _total_workers);
151 assert(v != 0, "Trying to set active workers to 0");
152 _active_workers = MAX2(1U, _active_workers);
153 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
154 "Unless dynamic should use total workers");
155 log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
156 }
157
158 // Return the Ith worker.
159 AbstractGangWorker* worker(uint i) const;
160
161 void threads_do(ThreadClosure* tc) const;
162
163 // Debugging.
164 const char* name() const { return _name; }
165
166 // Printing
167 void print_worker_threads_on(outputStream *st) const;
168 void print_worker_threads() const {
169 print_worker_threads_on(tty);
170 }
171
172 protected:
173 virtual AbstractGangWorker* allocate_worker(uint which) = 0;
174 };
175
176 // An class representing a gang of workers.
177 class WorkGang: public AbstractWorkGang {
178 // To get access to the GangTaskDispatcher instance.
179 friend class GangWorker;
180
181 // Never deleted.
|
95
96 // Waits for a task to become available to the worker.
97 // Returns when the worker has been assigned a task.
98 virtual WorkData worker_wait_for_task() = 0;
99
100 // Signal to the coordinator that the worker is done with the assigned task.
101 virtual void worker_done_with_task() = 0;
102 };
103
104 // The work gang is the collection of workers to execute tasks.
105 // The number of workers run for a task is "_active_workers"
106 // while "_total_workers" is the number of available of workers.
107 class AbstractWorkGang : public CHeapObj<mtInternal> {
108 protected:
109 // The array of worker threads for this gang.
110 AbstractGangWorker** _workers;
111 // The count of the number of workers in the gang.
112 uint _total_workers;
113 // The currently active workers in this gang.
114 uint _active_workers;
115 // The count of created workers in the gang.
116 uint _created_workers;
117 // Printing support.
118 const char* _name;
119
120 private:
121 // Initialize only instance data.
122 const bool _are_GC_task_threads;
123 const bool _are_ConcurrentGC_threads;
124
125 void set_thread(uint worker_id, AbstractGangWorker* worker) {
126 _workers[worker_id] = worker;
127 }
128
129 public:
130 AbstractWorkGang(const char* name, uint workers, bool are_GC_task_threads, bool are_ConcurrentGC_threads) :
131 _name(name),
132 _total_workers(workers),
133 _active_workers(UseDynamicNumberOfGCThreads ? 1U : workers),
134 _created_workers(0),
135 _are_GC_task_threads(are_GC_task_threads),
136 _are_ConcurrentGC_threads(are_ConcurrentGC_threads)
137 { }
138
139 // Initialize workers in the gang. Return true if initialization succeeded.
140 bool initialize_workers();
141
142 bool are_GC_task_threads() const { return _are_GC_task_threads; }
143 bool are_ConcurrentGC_threads() const { return _are_ConcurrentGC_threads; }
144
145 uint total_workers() const { return _total_workers; }
146
147 uint created_workers() const {
148 return _created_workers;
149 }
150
151 virtual uint active_workers() const {
152 assert(_active_workers <= _total_workers,
153 "_active_workers: %u > _total_workers: %u", _active_workers, _total_workers);
154 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
155 "Unless dynamic should use total workers");
156 return _active_workers;
157 }
158
159 void set_active_workers(uint v) {
160 assert(v <= _total_workers,
161 "Trying to set more workers active than there are");
162 _active_workers = MIN2(v, _total_workers);
163 add_workers(false /* exit_on_failure */);
164 assert(v != 0, "Trying to set active workers to 0");
165 assert(UseDynamicNumberOfGCThreads || _active_workers == _total_workers,
166 "Unless dynamic should use total workers");
167 log_info(gc, task)("GC Workers: using %d out of %d", _active_workers, _total_workers);
168 }
169
170 // Add GC workers as needed.
171 bool add_workers(bool initializing);
172
173 // Return the Ith worker.
174 AbstractGangWorker* worker(uint i) const;
175
176 void threads_do(ThreadClosure* tc) const;
177
178 // Create a GC worker and install it into the work gang.
179 virtual AbstractGangWorker* install_worker(uint which);
180
181 // Debugging.
182 const char* name() const { return _name; }
183
184 // Printing
185 void print_worker_threads_on(outputStream *st) const;
186 void print_worker_threads() const {
187 print_worker_threads_on(tty);
188 }
189
190 protected:
191 virtual AbstractGangWorker* allocate_worker(uint which) = 0;
192 };
193
194 // An class representing a gang of workers.
195 class WorkGang: public AbstractWorkGang {
196 // To get access to the GangTaskDispatcher instance.
197 friend class GangWorker;
198
199 // Never deleted.
|