8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_UTILITIES_CONCURRENT_HASH_TABLE_TASKS_INLINE_HPP
26 #define SHARE_UTILITIES_CONCURRENT_HASH_TABLE_TASKS_INLINE_HPP
27
28 #include "utilities/concurrentHashTable.inline.hpp"
29
30 // This inline file contains BulkDeleteTask and GrowTasks which are both bucket
31 // operations, which they are serialized with each other.
32
33 // Base class for pause and/or parallel bulk operations.
34 template <typename VALUE, typename CONFIG, MEMFLAGS F>
35 class ConcurrentHashTable<VALUE, CONFIG, F>::BucketsOperation {
36 protected:
37 ConcurrentHashTable<VALUE, CONFIG, F>* _cht;
38
39 // Default size of _task_size_log2
40 static const size_t DEFAULT_TASK_SIZE_LOG2 = 12;
41
42 // The table is split into ranges, every increment is one range.
43 volatile size_t _next_to_claim;
44 size_t _task_size_log2; // Number of buckets.
45 size_t _stop_task; // Last task
46 size_t _size_log2; // Table size.
47
48 BucketsOperation(ConcurrentHashTable<VALUE, CONFIG, F>* cht)
49 : _cht(cht), _next_to_claim(0), _task_size_log2(DEFAULT_TASK_SIZE_LOG2),
50 _stop_task(0), _size_log2(0) {}
51
52 // Returns true if you succeeded to claim the range start -> (stop-1).
53 bool claim(size_t* start, size_t* stop) {
54 size_t claimed = Atomic::add((size_t)1, &_next_to_claim) - 1;
55 if (claimed >= _stop_task) {
56 return false;
57 }
58 *start = claimed * (((size_t)1) << _task_size_log2);
59 *stop = ((*start) + (((size_t)1) << _task_size_log2));
60 return true;
61 }
62
63 // Calculate starting values.
64 void setup() {
65 _size_log2 = _cht->_table->_log2_size;
66 size_t tmp = _size_log2 > _task_size_log2 ?
67 _size_log2 - _task_size_log2 : 0;
68 _stop_task = (((size_t)1) << tmp);
69 }
70
71 // Returns false if all ranges are claimed.
72 bool have_more_work() {
73 return OrderAccess::load_acquire(&_next_to_claim) >= _stop_task;
74 }
75
76 // If we have changed size.
77 bool is_same_table() {
78 // Not entirely true.
79 return _size_log2 != _cht->_table->_log2_size;
80 }
81
82 void thread_owns_resize_lock(Thread* thread) {
83 assert(BucketsOperation::_cht->_resize_lock_owner == thread,
84 "Should be locked by me");
85 assert(BucketsOperation::_cht->_resize_lock->owned_by_self(),
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_UTILITIES_CONCURRENT_HASH_TABLE_TASKS_INLINE_HPP
26 #define SHARE_UTILITIES_CONCURRENT_HASH_TABLE_TASKS_INLINE_HPP
27
28 #include "utilities/globalDefinitions.hpp"
29 #include "utilities/concurrentHashTable.inline.hpp"
30
31 // This inline file contains BulkDeleteTask and GrowTasks which are both bucket
32 // operations, which they are serialized with each other.
33
34 // Base class for pause and/or parallel bulk operations.
35 template <typename VALUE, typename CONFIG, MEMFLAGS F>
36 class ConcurrentHashTable<VALUE, CONFIG, F>::BucketsOperation {
37 protected:
38 ConcurrentHashTable<VALUE, CONFIG, F>* _cht;
39
40 // Default size of _task_size_log2
41 static const size_t DEFAULT_TASK_SIZE_LOG2 = 12;
42
43 // The table is split into ranges, every increment is one range.
44 volatile size_t _next_to_claim;
45 size_t _task_size_log2; // Number of buckets.
46 size_t _stop_task; // Last task
47 size_t _size_log2; // Table size.
48
49 BucketsOperation(ConcurrentHashTable<VALUE, CONFIG, F>* cht)
50 : _cht(cht), _next_to_claim(0), _task_size_log2(DEFAULT_TASK_SIZE_LOG2),
51 _stop_task(0), _size_log2(0) {}
52
53 // Returns true if you succeeded to claim the range start -> (stop-1).
54 bool claim(size_t* start, size_t* stop) {
55 size_t claimed = Atomic::add((size_t)1, &_next_to_claim) - 1;
56 if (claimed >= _stop_task) {
57 return false;
58 }
59 *start = claimed * (((size_t)1) << _task_size_log2);
60 *stop = ((*start) + (((size_t)1) << _task_size_log2));
61 return true;
62 }
63
64 // Calculate starting values.
65 void setup() {
66 _size_log2 = _cht->_table->_log2_size;
67 _task_size_log2 = MIN2(_task_size_log2, _size_log2);
68 size_t tmp = _size_log2 > _task_size_log2 ?
69 _size_log2 - _task_size_log2 : 0;
70 _stop_task = (((size_t)1) << tmp);
71 }
72
73 // Returns false if all ranges are claimed.
74 bool have_more_work() {
75 return OrderAccess::load_acquire(&_next_to_claim) >= _stop_task;
76 }
77
78 // If we have changed size.
79 bool is_same_table() {
80 // Not entirely true.
81 return _size_log2 != _cht->_table->_log2_size;
82 }
83
84 void thread_owns_resize_lock(Thread* thread) {
85 assert(BucketsOperation::_cht->_resize_lock_owner == thread,
86 "Should be locked by me");
87 assert(BucketsOperation::_cht->_resize_lock->owned_by_self(),
|