Warning, file /include/oneapi/tbb/global_control.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_global_control_H
0018 #define __TBB_global_control_H
0019
0020 #include "detail/_config.h"
0021
0022 #include "detail/_assert.h"
0023 #include "detail/_attach.h"
0024 #include "detail/_exception.h"
0025 #include "detail/_namespace_injection.h"
0026 #include "detail/_template_helpers.h"
0027
0028 #include <cstddef>
0029 #include <new> // std::nothrow_t
0030
0031 namespace tbb {
0032 namespace detail {
0033
0034 namespace d1 {
0035 class global_control;
0036 class task_scheduler_handle;
0037 }
0038
0039 namespace r1 {
0040 TBB_EXPORT void __TBB_EXPORTED_FUNC create(d1::global_control&);
0041 TBB_EXPORT void __TBB_EXPORTED_FUNC destroy(d1::global_control&);
0042 TBB_EXPORT std::size_t __TBB_EXPORTED_FUNC global_control_active_value(int);
0043 struct global_control_impl;
0044 struct control_storage_comparator;
0045 void release_impl(d1::task_scheduler_handle& handle);
0046 bool finalize_impl(d1::task_scheduler_handle& handle);
0047 TBB_EXPORT void __TBB_EXPORTED_FUNC get(d1::task_scheduler_handle&);
0048 TBB_EXPORT bool __TBB_EXPORTED_FUNC finalize(d1::task_scheduler_handle&, std::intptr_t mode);
0049 }
0050
0051 namespace d1 {
0052
0053 class global_control {
0054 public:
0055 enum parameter {
0056 max_allowed_parallelism,
0057 thread_stack_size,
0058 terminate_on_exception,
0059 scheduler_handle,
0060 parameter_max
0061 };
0062
0063 global_control(parameter p, std::size_t value) :
0064 my_value(value), my_reserved(), my_param(p) {
0065 suppress_unused_warning(my_reserved);
0066 __TBB_ASSERT(my_param < parameter_max, "Invalid parameter");
0067 #if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
0068
0069 if (p==thread_stack_size)
0070 return;
0071 #elif __TBB_x86_64 && (_WIN32 || _WIN64)
0072 if (p==thread_stack_size)
0073 __TBB_ASSERT_RELEASE((unsigned)value == value, "Stack size is limited to unsigned int range");
0074 #endif
0075 if (my_param==max_allowed_parallelism)
0076 __TBB_ASSERT_RELEASE(my_value>0, "max_allowed_parallelism cannot be 0.");
0077 r1::create(*this);
0078 }
0079
0080 ~global_control() {
0081 __TBB_ASSERT(my_param < parameter_max, "Invalid parameter");
0082 #if __TBB_WIN8UI_SUPPORT && (_WIN32_WINNT < 0x0A00)
0083
0084 if (my_param==thread_stack_size)
0085 return;
0086 #endif
0087 r1::destroy(*this);
0088 }
0089
0090 static std::size_t active_value(parameter p) {
0091 __TBB_ASSERT(p < parameter_max, "Invalid parameter");
0092 return r1::global_control_active_value((int)p);
0093 }
0094
0095 private:
0096 std::size_t my_value;
0097 std::intptr_t my_reserved;
0098 parameter my_param;
0099
0100 friend struct r1::global_control_impl;
0101 friend struct r1::control_storage_comparator;
0102 };
0103
0104
0105
0106 static constexpr std::intptr_t release_nothrowing = 0;
0107 static constexpr std::intptr_t finalize_nothrowing = 1;
0108 static constexpr std::intptr_t finalize_throwing = 2;
0109
0110
0111 class task_scheduler_handle {
0112 public:
0113
0114 task_scheduler_handle() = default;
0115
0116
0117 task_scheduler_handle(attach) {
0118 r1::get(*this);
0119 }
0120
0121
0122 ~task_scheduler_handle() {
0123 release();
0124 }
0125
0126
0127 task_scheduler_handle(const task_scheduler_handle& other) = delete;
0128 task_scheduler_handle& operator=(const task_scheduler_handle& other) = delete;
0129
0130
0131 task_scheduler_handle(task_scheduler_handle&& other) noexcept {
0132 std::swap(m_ctl, other.m_ctl);
0133 }
0134 task_scheduler_handle& operator=(task_scheduler_handle&& other) noexcept {
0135 std::swap(m_ctl, other.m_ctl);
0136 return *this;
0137 };
0138
0139
0140 explicit operator bool() const noexcept {
0141 return m_ctl != nullptr;
0142 }
0143
0144
0145 void release() {
0146 if (m_ctl != nullptr) {
0147 r1::finalize(*this, release_nothrowing);
0148 m_ctl = nullptr;
0149 }
0150 }
0151
0152 private:
0153 friend void r1::release_impl(task_scheduler_handle& handle);
0154 friend bool r1::finalize_impl(task_scheduler_handle& handle);
0155 friend void __TBB_EXPORTED_FUNC r1::get(task_scheduler_handle&);
0156
0157 friend void finalize(task_scheduler_handle&);
0158 friend bool finalize(task_scheduler_handle&, const std::nothrow_t&) noexcept;
0159
0160 global_control* m_ctl{nullptr};
0161 };
0162
0163 #if TBB_USE_EXCEPTIONS
0164
0165 inline void finalize(task_scheduler_handle& handle) {
0166 try_call([&] {
0167 if (handle.m_ctl != nullptr) {
0168 bool finalized = r1::finalize(handle, finalize_throwing);
0169 __TBB_ASSERT_EX(finalized, "r1::finalize did not respect finalize_throwing ?");
0170
0171 }
0172 }).on_completion([&] {
0173 __TBB_ASSERT(!handle, "The handle should be empty after finalize");
0174 });
0175 }
0176 #endif
0177
0178 inline bool finalize(task_scheduler_handle& handle, const std::nothrow_t&) noexcept {
0179 bool finalized = true;
0180 if (handle.m_ctl != nullptr) {
0181 finalized = r1::finalize(handle, finalize_nothrowing);
0182 }
0183 __TBB_ASSERT(!handle, "The handle should be empty after finalize");
0184 return finalized;
0185 }
0186
0187 }
0188 }
0189
0190 inline namespace v1 {
0191 using detail::d1::global_control;
0192 using detail::d1::attach;
0193 using detail::d1::finalize;
0194 using detail::d1::task_scheduler_handle;
0195 using detail::r1::unsafe_wait;
0196 }
0197
0198 }
0199
0200 #endif