1 /* |
1 /* |
2 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2005, 2010 Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
50 YieldingFlexibleWorkGang* yf_gang() const |
50 YieldingFlexibleWorkGang* yf_gang() const |
51 { return (YieldingFlexibleWorkGang*)gang(); } |
51 { return (YieldingFlexibleWorkGang*)gang(); } |
52 |
52 |
53 protected: // Override from parent class |
53 protected: // Override from parent class |
54 virtual void loop(); |
54 virtual void loop(); |
|
55 }; |
|
56 |
|
57 class FlexibleGangTask: public AbstractGangTask { |
|
58 int _actual_size; // size of gang obtained |
|
59 protected: |
|
60 int _requested_size; // size of gang requested |
|
61 public: |
|
62 FlexibleGangTask(const char* name): AbstractGangTask(name), |
|
63 _requested_size(0) {} |
|
64 |
|
65 // The abstract work method. |
|
66 // The argument tells you which member of the gang you are. |
|
67 virtual void work(int i) = 0; |
|
68 |
|
69 int requested_size() const { return _requested_size; } |
|
70 int actual_size() const { return _actual_size; } |
|
71 |
|
72 void set_requested_size(int sz) { _requested_size = sz; } |
|
73 void set_actual_size(int sz) { _actual_size = sz; } |
55 }; |
74 }; |
56 |
75 |
57 // An abstract task to be worked on by a flexible work gang, |
76 // An abstract task to be worked on by a flexible work gang, |
58 // and where the workers will periodically yield, usually |
77 // and where the workers will periodically yield, usually |
59 // in response to some condition that is signalled by means |
78 // in response to some condition that is signalled by means |
68 // gang workers waiting on the bench; in other words, the |
87 // gang workers waiting on the bench; in other words, the |
69 // size of the active worker pool can flex (up to an apriori |
88 // size of the active worker pool can flex (up to an apriori |
70 // maximum) in response to task requests at certain points. |
89 // maximum) in response to task requests at certain points. |
71 // The last part (the flexible part) has not yet been fully |
90 // The last part (the flexible part) has not yet been fully |
72 // fleshed out and is a work in progress. |
91 // fleshed out and is a work in progress. |
73 class YieldingFlexibleGangTask: public AbstractGangTask { |
92 class YieldingFlexibleGangTask: public FlexibleGangTask { |
74 Status _status; |
93 Status _status; |
75 YieldingFlexibleWorkGang* _gang; |
94 YieldingFlexibleWorkGang* _gang; |
76 int _actual_size; // size of gang obtained |
|
77 |
95 |
78 protected: |
96 protected: |
79 int _requested_size; // size of gang requested |
|
80 |
|
81 // Constructor and desctructor: only construct subclasses. |
97 // Constructor and desctructor: only construct subclasses. |
82 YieldingFlexibleGangTask(const char* name): AbstractGangTask(name), |
98 YieldingFlexibleGangTask(const char* name): FlexibleGangTask(name), |
83 _status(INACTIVE), |
99 _status(INACTIVE), |
84 _gang(NULL), |
100 _gang(NULL) { } |
85 _requested_size(0) { } |
|
86 |
101 |
87 virtual ~YieldingFlexibleGangTask() { } |
102 virtual ~YieldingFlexibleGangTask() { } |
88 |
103 |
89 friend class YieldingFlexibleWorkGang; |
104 friend class YieldingFlexibleWorkGang; |
90 friend class YieldingFlexibleGangWorker; |
105 friend class YieldingFlexibleGangWorker; |
124 Status status() const { return _status; } |
139 Status status() const { return _status; } |
125 bool yielded() const { return _status == YIELDED; } |
140 bool yielded() const { return _status == YIELDED; } |
126 bool completed() const { return _status == COMPLETED; } |
141 bool completed() const { return _status == COMPLETED; } |
127 bool aborted() const { return _status == ABORTED; } |
142 bool aborted() const { return _status == ABORTED; } |
128 bool active() const { return _status == ACTIVE; } |
143 bool active() const { return _status == ACTIVE; } |
129 |
144 }; |
130 int requested_size() const { return _requested_size; } |
|
131 int actual_size() const { return _actual_size; } |
|
132 |
|
133 void set_requested_size(int sz) { _requested_size = sz; } |
|
134 void set_actual_size(int sz) { _actual_size = sz; } |
|
135 }; |
|
136 |
|
137 // Class YieldingWorkGang: A subclass of WorkGang. |
145 // Class YieldingWorkGang: A subclass of WorkGang. |
138 // In particular, a YieldingWorkGang is made up of |
146 // In particular, a YieldingWorkGang is made up of |
139 // YieldingGangWorkers, and provides infrastructure |
147 // YieldingGangWorkers, and provides infrastructure |
140 // supporting yielding to the "GangOverseer", |
148 // supporting yielding to the "GangOverseer", |
141 // being the thread that orchestrates the WorkGang via run_task(). |
149 // being the thread that orchestrates the WorkGang via run_task(). |
142 class YieldingFlexibleWorkGang: public AbstractWorkGang { |
150 class YieldingFlexibleWorkGang: public FlexibleWorkGang { |
143 // Here's the public interface to this class. |
151 // Here's the public interface to this class. |
144 public: |
152 public: |
145 // Constructor and destructor. |
153 // Constructor and destructor. |
146 YieldingFlexibleWorkGang(const char* name, int workers, |
154 YieldingFlexibleWorkGang(const char* name, int workers, |
147 bool are_GC_task_threads); |
155 bool are_GC_task_threads); |
149 YieldingFlexibleGangTask* yielding_task() const { |
157 YieldingFlexibleGangTask* yielding_task() const { |
150 assert(task() == NULL || task()->is_YieldingFlexibleGang_task(), |
158 assert(task() == NULL || task()->is_YieldingFlexibleGang_task(), |
151 "Incorrect cast"); |
159 "Incorrect cast"); |
152 return (YieldingFlexibleGangTask*)task(); |
160 return (YieldingFlexibleGangTask*)task(); |
153 } |
161 } |
|
162 // Allocate a worker and return a pointer to it. |
|
163 GangWorker* allocate_worker(int which); |
|
164 |
154 // Run a task; returns when the task is done, or the workers yield, |
165 // Run a task; returns when the task is done, or the workers yield, |
155 // or the task is aborted, or the work gang is terminated via stop(). |
166 // or the task is aborted, or the work gang is terminated via stop(). |
156 // A task that has been yielded can be continued via this same interface |
167 // A task that has been yielded can be continued via this same interface |
157 // by using the same task repeatedly as the argument to the call. |
168 // by using the same task repeatedly as the argument to the call. |
158 // It is expected that the YieldingFlexibleGangTask carries the appropriate |
169 // It is expected that the YieldingFlexibleGangTask carries the appropriate |
178 // stations, whence they are ready for the next task dispatched |
189 // stations, whence they are ready for the next task dispatched |
179 // by the overseer. |
190 // by the overseer. |
180 void abort(); |
191 void abort(); |
181 |
192 |
182 private: |
193 private: |
183 // The currently active workers in this gang. |
|
184 // This is a number that is dynamically adjusted by |
|
185 // the run_task() method at each subsequent invocation, |
|
186 // using data in the YieldingFlexibleGangTask. |
|
187 int _active_workers; |
194 int _active_workers; |
188 int _yielded_workers; |
195 int _yielded_workers; |
189 void wait_for_gang(); |
196 void wait_for_gang(); |
190 |
197 |
191 public: |
198 public: |
192 // Accessors for fields |
199 // Accessors for fields |
193 int active_workers() const { |
200 int active_workers() const { |
194 return _active_workers; |
201 return _active_workers; |
195 } |
202 } |
196 |
203 |
|
204 // Accessors for fields |
197 int yielded_workers() const { |
205 int yielded_workers() const { |
198 return _yielded_workers; |
206 return _yielded_workers; |
199 } |
207 } |
200 |
208 |
201 private: |
209 private: |