3232#include " runtime/os.hpp"
3333#include " runtime/thread.hpp"
3434#include " utilities/align.hpp"
35+ #include " utilities/powerOfTwo.hpp"
3536
3637class ZIndexDistributorStriped : public CHeapObj <mtGC> {
3738 static const int MemSize = 4096 ;
39+ static const int StripeCount = MemSize / ZCacheLineSize;
3840
39- const int _max_index ;
41+ const int _count ;
4042 // For claiming a stripe
4143 volatile int _claim_stripe;
4244 // For claiming inside a stripe
@@ -51,20 +53,19 @@ class ZIndexDistributorStriped : public CHeapObj<mtGC> {
5153 }
5254
5355public:
54- ZIndexDistributorStriped (int max_index )
55- : _max_index(max_index ),
56+ ZIndexDistributorStriped (int count )
57+ : _count(count ),
5658 _claim_stripe (0 ),
5759 _mem() {
5860 memset (_mem, 0 , MemSize + ZCacheLineSize);
5961 }
6062
6163 template <typename Function>
6264 void do_indices (Function function) {
63- const int count = MemSize / ZCacheLineSize;
64- const int stripe_max = _max_index / count;
65+ const int stripe_max = _count / StripeCount;
6566
6667 // Use claiming
67- for (int i; (i = claim_stripe ()) < count ;) {
68+ for (int i; (i = claim_stripe ()) < StripeCount ;) {
6869 for (int index; (index = Atomic::fetch_then_add (claim_addr (i), 1 , memory_order_relaxed)) < stripe_max;) {
6970 if (!function (i * stripe_max + index)) {
7071 return ;
@@ -73,14 +74,19 @@ class ZIndexDistributorStriped : public CHeapObj<mtGC> {
7374 }
7475
7576 // Use stealing
76- for (int i = 0 ; i < count ; i++) {
77+ for (int i = 0 ; i < StripeCount ; i++) {
7778 for (int index; (index = Atomic::fetch_then_add (claim_addr (i), 1 , memory_order_relaxed)) < stripe_max;) {
7879 if (!function (i * stripe_max + index)) {
7980 return ;
8081 }
8182 }
8283 }
8384 }
85+
86+ static size_t get_count (size_t max_count) {
87+ // Must be multiple of the StripeCount
88+ return align_up (max_count, StripeCount);
89+ }
8490};
8591
8692class ZIndexDistributorClaimTree : public CHeapObj <mtGC> {
@@ -290,6 +296,12 @@ class ZIndexDistributorClaimTree : public CHeapObj<mtGC> {
290296 claim_and_do (function, indices, 0 /* level */ );
291297 steal_and_do (function, indices, 0 /* level */ );
292298 }
299+
300+ static size_t get_count (size_t max_count) {
301+ // Must be at least claim_level_size(ClaimLevels) and a power of two
302+ const size_t min_count = claim_level_size (ClaimLevels);
303+ return round_up_power_of_2 (MAX2 (max_count, min_count));
304+ }
293305};
294306
295307// Using dynamically allocated objects just to be able to evaluate
@@ -328,4 +340,17 @@ inline void ZIndexDistributor::do_indices(Function function) {
328340 };
329341}
330342
343+ inline size_t ZIndexDistributor::get_count (size_t max_count) {
344+ size_t required_count;
345+ switch (ZIndexDistributorStrategy) {
346+ case 0 : required_count = ZIndexDistributorClaimTree::get_count (max_count); break ;
347+ case 1 : required_count = ZIndexDistributorStriped::get_count (max_count); break ;
348+ default : fatal (" Unknown ZIndexDistributorStrategy" );
349+ };
350+
351+ assert (max_count <= required_count, " unsupported max_count: %zu" , max_count);
352+
353+ return required_count;
354+ }
355+
331356#endif // SHARE_GC_Z_ZINDEXDISTRIBUTOR_INLINE_HPP
0 commit comments