File indexing completed on 2025-01-18 10:12:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB__aggregator_H
0018 #define __TBB__aggregator_H
0019
0020 #define __TBB_aggregator_H_include_area
0021 #include "internal/_warning_suppress_enable_notice.h"
0022
0023 #if !TBB_PREVIEW_AGGREGATOR
0024 #error Set TBB_PREVIEW_AGGREGATOR before including aggregator.h
0025 #endif
0026
0027 #include "atomic.h"
0028 #include "tbb_profiling.h"
0029
0030 namespace tbb {
0031 namespace interface6 {
0032
0033 using namespace tbb::internal;
0034
0035 class aggregator_operation {
0036 template<typename handler_type> friend class aggregator_ext;
0037 uintptr_t status;
0038 aggregator_operation* my_next;
0039 public:
0040 enum aggregator_operation_status { agg_waiting=0, agg_finished };
0041 aggregator_operation() : status(agg_waiting), my_next(NULL) {}
0042
0043 void start() { call_itt_notify(acquired, &status); }
0044
0045
0046 void finish() { itt_store_word_with_release(status, uintptr_t(agg_finished)); }
0047 aggregator_operation* next() { return itt_hide_load_word(my_next);}
0048 void set_next(aggregator_operation* n) { itt_hide_store_word(my_next, n); }
0049 };
0050
0051 namespace internal {
0052
0053 class basic_operation_base : public aggregator_operation {
0054 friend class basic_handler;
0055 virtual void apply_body() = 0;
0056 public:
0057 basic_operation_base() : aggregator_operation() {}
0058 virtual ~basic_operation_base() {}
0059 };
0060
0061 template<typename Body>
0062 class basic_operation : public basic_operation_base, no_assign {
0063 const Body& my_body;
0064 void apply_body() __TBB_override { my_body(); }
0065 public:
0066 basic_operation(const Body& b) : basic_operation_base(), my_body(b) {}
0067 };
0068
0069 class basic_handler {
0070 public:
0071 basic_handler() {}
0072 void operator()(aggregator_operation* op_list) const {
0073 while (op_list) {
0074
0075
0076
0077
0078
0079
0080 basic_operation_base& request = static_cast<basic_operation_base&>(*op_list);
0081
0082 op_list = op_list->next();
0083 request.start();
0084 request.apply_body();
0085 request.finish();
0086 }
0087 }
0088 };
0089
0090 }
0091
0092
0093
0094
0095 template <typename handler_type>
0096 class aggregator_ext : tbb::internal::no_copy {
0097 public:
0098 aggregator_ext(const handler_type& h) : handler_busy(0), handle_operations(h) { mailbox = NULL; }
0099
0100
0101
0102 void process(aggregator_operation *op) { execute_impl(*op); }
0103
0104 protected:
0105
0106
0107 void execute_impl(aggregator_operation& op) {
0108 aggregator_operation* res;
0109
0110
0111
0112
0113
0114
0115 call_itt_notify(releasing, &(op.status));
0116
0117 do {
0118
0119
0120 op.my_next = res = mailbox;
0121 } while (mailbox.compare_and_swap(&op, res) != res);
0122 if (!res) {
0123
0124
0125 call_itt_notify(acquired, &mailbox);
0126 start_handle_operations();
0127 __TBB_ASSERT(op.status, NULL);
0128 }
0129 else {
0130 call_itt_notify(prepare, &(op.status));
0131 spin_wait_while_eq(op.status, uintptr_t(aggregator_operation::agg_waiting));
0132 itt_load_word_with_acquire(op.status);
0133 }
0134 }
0135
0136
0137 private:
0138
0139 atomic<aggregator_operation *> mailbox;
0140
0141
0142
0143 uintptr_t handler_busy;
0144
0145 handler_type handle_operations;
0146
0147
0148 void start_handle_operations() {
0149 aggregator_operation *pending_operations;
0150
0151
0152
0153
0154
0155
0156
0157 call_itt_notify(prepare, &handler_busy);
0158
0159 spin_wait_until_eq(handler_busy, uintptr_t(0));
0160 call_itt_notify(acquired, &handler_busy);
0161
0162 __TBB_store_with_release(handler_busy, uintptr_t(1));
0163
0164
0165
0166
0167 call_itt_notify(releasing, &mailbox);
0168
0169 pending_operations = mailbox.fetch_and_store(NULL);
0170
0171
0172 handle_operations(pending_operations);
0173
0174
0175 itt_store_word_with_release(handler_busy, uintptr_t(0));
0176 }
0177 };
0178
0179
0180 class aggregator : private aggregator_ext<internal::basic_handler> {
0181 public:
0182 aggregator() : aggregator_ext<internal::basic_handler>(internal::basic_handler()) {}
0183
0184
0185
0186 template<typename Body>
0187 void execute(const Body& b) {
0188 internal::basic_operation<Body> op(b);
0189 this->execute_impl(op);
0190 }
0191 };
0192
0193 }
0194
0195 using interface6::aggregator;
0196 using interface6::aggregator_ext;
0197 using interface6::aggregator_operation;
0198
0199 }
0200
0201 #include "internal/_warning_suppress_disable_notice.h"
0202 #undef __TBB_aggregator_H_include_area
0203
0204 #endif