BitMagic-C++
bmtask.h
Go to the documentation of this file.
1#ifndef BMTASK__H__INCLUDED__
2#define BMTASK__H__INCLUDED__
3/*
4Copyright(c) 2020 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17
18For more information please visit: http://bitmagic.io
19*/
20
21/*! \file bmtask.h
22 \brief Task definitions for parallel programming with BitMagic
23
24 The design intent is to make tasks reasonably compatible with
25 different threading and execution models, possibly with different
26 languages and non-C++ runtimes.
27
28*/
29#include <atomic>
30#include <functional>
31#include <vector>
32
33
34#include "bmbuffer.h"
35
36namespace bm
37{
38
39/** @defgroup bmtasks Task parallel programming
40 Task parallel programming compatible with different execution models
41 and runtimes
42
43 @ingroup bmagic
44*/
45
46/** Typedef for a call-back function pointer (pthread conformant signature)
47 @ingroup bmtasks
48*/
49typedef void* (*task_func_type)(void*);
50
51/** Typedef for a call-back functional for lambda capture
52 @ingroup bmtasks
53*/
54typedef std::function<int(void*)> task_function_t;
55
56
57
58/** BitMagic task with a captured function
59 @ingroup bmtasks
60*/
62{
64 {
65 no_flag = 0, ///< no flag specified
66 barrier_ok = 1u, ///< barrier waits all prev.tasks done without error
67 barrier_any = (1u << 1), ///< barrier waits all prev tasks done (success or not)
69 };
70
71 task_function_t func; ///< captured function callback
72 void* argp; ///< arg pointer
73
74
75 bm::id64_t flags; ///< task flags to designate barriers
76 int err_code; ///< error code
77 std::atomic_bool done; ///< 0 - pending
78
79 // ----------------------------------------------------
80 // Construction
81 //
83
85 {
86 func = td.func;
87 argp = td.argp;
88 flags = td.flags;
89 err_code = td.err_code;
90 done.store(td.done.load()); // atomic operation
91 }
92
93 task_descr(task_function_t f, void* argptr = 0) noexcept
94 {
95 this->init(f, argptr);
96 }
97
98 void init(task_function_t f, void* argptr) noexcept
99 {
100 func = f; argp = argptr; done = 0; flags = no_flag;
101 }
102
103 int run()
104 {
105 err_code = func(argp);
106 done.store(1, std::memory_order_release);
107 return err_code;
108 }
109};
110
111
112
113/**
114 Interface definition (base class) for a group of tasks (batch)
115 @ingroup bmtasks
116 */
118{
119public:
120 typedef unsigned size_type;
121public:
122 virtual ~task_batch_base() {}
123
124 /// Return size of batch
125 virtual size_type size() const = 0;
126
127 /// Get task by index in the batch
128 /// @param task_idx - task index in the batch
129 /// @return task description
130 virtual bm::task_descr* get_task(size_type task_idx) = 0;
131
132};
133
134/**
135 Basic implementation for collection of tasks for parallel execution
136 @ingroup bmtasks
137 */
138template<typename BVAlloc>
140{
141public:
142 typedef BVAlloc bv_allocator_type;
144
145 typedef
146 std::vector<bm::task_descr> task_vector_type;
147
148 // disabled (error aunder MSVC related to vector impl for complex types
149 #if 0
150 typedef
151 bm::heap_vector<bm::task_descr, bv_allocator_type, true> task_vector_type;
152 #endif
153
154public:
155
156 /// task_batch_base intreface implementation
157 //@{
158 virtual size_type size() const BMNOEXCEPT { return (size_type) task_vect_.size(); }
159 virtual
161 { return &task_vect_[task_idx]; }
162
163 //@}
164
165
166 /// Get access to internal task vector
167 ///
171
172 void add(task_function_t f, void* argptr)
173 {
174 task_vect_.emplace_back(bm::task_descr(f, argptr));
175// bm::task_descr& tdescr = task_vect_.add();
176// tdescr.init(f, argptr);
177 }
178
179protected:
180 task_vector_type task_vect_; ///< list of tasks
181};
182
183
184/**
185 Run task batch sequentially
186
187 Function is used for testing and debugging purposes or as a reference
188 to implement custom parallel executors.
189
190 @param tasks - collection of tasks to run
191 @ingroup bmtasks
192 */
193inline
195{
196 task_batch_base::size_type batch_size = tasks.size();
197 for (task_batch_base::size_type i = 0; i < batch_size; ++i)
198 {
199 bm::task_descr* tdescr = tasks.get_task(i);
200 tdescr->argp = tdescr; // restore the self referenece
201 tdescr->run();
202 } // for
203}
204
205
206/**
207 "noexcept" traits detection for T::lock()
208 @internal
209 @ingroup bmtasks
210 */
211template <typename T>
213{
214#if BM_DONT_WANT_TYPE_TRAITS_HEADER // not used
215 constexpr static bool value = noexcept(((T*)nullptr)->lock());
216#else
217 constexpr static bool value = noexcept(std::declval<T>().lock());
218#endif
219};
220
221/**
222 Simple scoped lock guard
223 @internal
224 @ingroup bmtasks
225 */
226template<typename Lock> class lock_guard
227{
228public:
230 : lk_(lk) {
231 lk_.lock();
232 }
233 ~lock_guard() { lk_.unlock(); }
234private:
235 lock_guard(const lock_guard<Lock>&) = delete;
236 lock_guard<Lock>& operator=(const lock_guard<Lock>&) = delete;
237private:
238 Lock& lk_;
239};
240
241
242
243} // namespace bm
244
245#endif
246
#define BMNOEXCEPT
Definition bmdef.h:82
Simple scoped lock guard.
Definition bmtask.h:227
lock_guard(Lock &lk) noexcept(bm::is_lock_noexcept< Lock >::value)
Definition bmtask.h:229
Interface definition (base class) for a group of tasks (batch).
Definition bmtask.h:118
virtual size_type size() const =0
Return size of batch.
virtual ~task_batch_base()
Definition bmtask.h:122
virtual bm::task_descr * get_task(size_type task_idx)=0
Get task by index in the batch.
unsigned size_type
Definition bmtask.h:120
Basic implementation for collection of tasks for parallel execution.
Definition bmtask.h:140
task_vector_type & get_task_vector() BMNOEXCEPT
Get access to internal task vector.
Definition bmtask.h:168
const task_vector_type & get_task_vector() const BMNOEXCEPT
Definition bmtask.h:169
BVAlloc bv_allocator_type
Definition bmtask.h:142
virtual size_type size() const BMNOEXCEPT
task_batch_base intreface implementation
Definition bmtask.h:158
task_batch_base::size_type size_type
Definition bmtask.h:143
void add(task_function_t f, void *argptr)
Definition bmtask.h:172
std::vector< bm::task_descr > task_vector_type
Definition bmtask.h:146
virtual bm::task_descr * get_task(size_type task_idx)
Get task by index in the batch.
Definition bmtask.h:160
task_vector_type task_vect_
Definition bmtask.h:180
std::function< int(void *)> task_function_t
Typedef for a call-back functional for lambda capture.
Definition bmtask.h:54
void run_task_batch(task_batch_base &tasks)
Run task batch sequentially.
Definition bmtask.h:194
Definition bm.h:78
unsigned long long int id64_t
Definition bmconst.h:35
"noexcept" traits detection for T::lock()
Definition bmtask.h:213
static constexpr bool value
Definition bmtask.h:217
BitMagic task with a captured function.
Definition bmtask.h:62
task_descr(task_function_t f, void *argptr=0) noexcept
Definition bmtask.h:93
void * argp
arg pointer
Definition bmtask.h:72
std::atomic_bool done
0 - pending
Definition bmtask.h:77
task_descr(const task_descr &td)
Definition bmtask.h:84
@ barrier_ok
barrier waits all prev.tasks done without error
Definition bmtask.h:66
@ barrier_ok_delayed
Definition bmtask.h:68
@ no_flag
no flag specified
Definition bmtask.h:65
@ barrier_any
barrier waits all prev tasks done (success or not)
Definition bmtask.h:67
bm::id64_t flags
task flags to designate barriers
Definition bmtask.h:75
task_descr() BMNOEXCEPT
Definition bmtask.h:82
task_function_t func
captured function callback
Definition bmtask.h:71
void init(task_function_t f, void *argptr) noexcept
Definition bmtask.h:98
int err_code
error code
Definition bmtask.h:76