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)
68 barrier_ok_delayed = (1u << 2)
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 ///
170 { return task_vect_; }
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
unsigned size_type
Definition: bmtask.h:120
virtual bm::task_descr * get_task(size_type task_idx)=0
Get task by index in the batch.
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_
list of tasks
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
constexpr static 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
int run()
Definition: bmtask.h:103
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