bmtask.h
Go to the documentation of this file.
#ifndef BMTASK__H__INCLUDED__
#define BMTASK__H__INCLUDED__
/*
Copyright(c) 2020 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information please visit: http://bitmagic.io
*/
/*! \file bmtask.h
\brief Task definitions for parallel programming with BitMagic
The design intent is to make tasks reasonably compatible with
different threading and execution models, possibly with different
languages and non-C++ runtimes.
*/
#include <atomic>
#include <functional>
#include <vector>
#include "bmbuffer.h"
namespace bm
{
/** @defgroup bmtasks Task parallel programming
Task parallel programming compatible with different execution models
and runtimes
@ingroup bmagic
*/
/** Typedef for a call-back function pointer (pthread conformant signature)
@ingroup bmtasks
*/
typedef void* (*task_func_type)(void*);
/** Typedef for a call-back functional for lambda capture
@ingroup bmtasks
*/
typedef std::function<int(void*)> task_function_t;
/** BitMagic task with a captured function
@ingroup bmtasks
*/
struct task_descr
{
enum task_flags
{
no_flag = 0, ///< no flag specified
barrier_ok = 1u, ///< barrier waits all prev.tasks done without error
barrier_any = (1u << 1), ///< barrier waits all prev tasks done (success or not)
barrier_ok_delayed = (1u << 2)
};
task_function_t func; ///< captured function callback
void* argp; ///< arg pointer
bm::id64_t flags; ///< task flags to designate barriers
int err_code; ///< error code
std::atomic_bool done; ///< 0 - pending
// ----------------------------------------------------
// Construction
//
task_descr() BMNOEXCEPT {}
task_descr(const task_descr& td)
{
func = td.func;
argp = td.argp;
flags = td.flags;
err_code = td.err_code;
done.store(td.done.load()); // atomic operation
}
task_descr(task_function_t f, void* argptr = 0) noexcept
{
this->init(f, argptr);
}
void init(task_function_t f, void* argptr) noexcept
{
func = f; argp = argptr; done = 0; flags = no_flag;
}
int run()
{
err_code = func(argp);
done.store(1, std::memory_order_release);
return err_code;
}
};
/**
Interface definition (base class) for a group of tasks (batch)
@ingroup bmtasks
*/
class task_batch_base
{
public:
typedef unsigned size_type;
public:
virtual ~task_batch_base() {}
/// Return size of batch
virtual size_type size() const = 0;
/// Get task by index in the batch
/// @param task_idx - task index in the batch
/// @return task description
virtual bm::task_descr* get_task(size_type task_idx) = 0;
};
/**
Basic implementation for collection of tasks for parallel execution
@ingroup bmtasks
*/
template<typename BVAlloc>
class task_batch : public task_batch_base
{
public:
typedef BVAlloc bv_allocator_type;
typedef task_batch_base::size_type size_type;
typedef
std::vector<bm::task_descr> task_vector_type;
// disabled (error aunder MSVC related to vector impl for complex types
#if 0
typedef
bm::heap_vector<bm::task_descr, bv_allocator_type, true> task_vector_type;
#endif
public:
/// task_batch_base intreface implementation
//@{
virtual size_type size() const BMNOEXCEPT { return (size_type) task_vect_.size(); }
virtual
bm::task_descr* get_task(size_type task_idx)
{ return &task_vect_[task_idx]; }
//@}
/// Get access to internal task vector
///
task_vector_type& get_task_vector() BMNOEXCEPT { return task_vect_; }
const task_vector_type& get_task_vector() const BMNOEXCEPT
{ return task_vect_; }
void add(task_function_t f, void* argptr)
{
task_vect_.emplace_back(bm::task_descr(f, argptr));
// bm::task_descr& tdescr = task_vect_.add();
// tdescr.init(f, argptr);
}
protected:
task_vector_type task_vect_; ///< list of tasks
};
/**
Run task batch sequentially
Function is used for testing and debugging purposes or as a reference
to implement custom parallel executors.
@param tasks - collection of tasks to run
@ingroup bmtasks
*/
inline
void run_task_batch(task_batch_base & tasks)
{
task_batch_base::size_type batch_size = tasks.size();
for (task_batch_base::size_type i = 0; i < batch_size; ++i)
{
bm::task_descr* tdescr = tasks.get_task(i);
tdescr->argp = tdescr; // restore the self referenece
tdescr->run();
} // for
}
/**
"noexcept" traits detection for T::lock()
@internal
@ingroup bmtasks
*/
template <typename T>
struct is_lock_noexcept
{
#if BM_DONT_WANT_TYPE_TRAITS_HEADER // not used
constexpr static bool value = noexcept(((T*)nullptr)->lock());
#else
constexpr static bool value = noexcept(std::declval<T>().lock());
#endif
};
/**
Simple scoped lock guard
@internal
@ingroup bmtasks
*/
template<typename Lock> class lock_guard
{
public:
lock_guard(Lock& lk) noexcept(bm::is_lock_noexcept<Lock>::value)
: lk_(lk) {
lk_.lock();
}
~lock_guard() { lk_.unlock(); }
private:
lock_guard(const lock_guard<Lock>&) = delete;
lock_guard<Lock>& operator=(const lock_guard<Lock>&) = delete;
private:
Lock& lk_;
};
} // namespace bm
#endif
BMNOEXCEPT
#define BMNOEXCEPT
Definition bmdef.h:82
bm::lock_guard
Simple scoped lock guard.
Definition bmtask.h:227
bm::lock_guard::lock_guard
lock_guard(Lock &lk) noexcept(bm::is_lock_noexcept< Lock >::value)
Definition bmtask.h:229
bm::lock_guard::~lock_guard
~lock_guard()
Definition bmtask.h:233
bm::task_batch_base
Interface definition (base class) for a group of tasks (batch).
Definition bmtask.h:118
bm::task_batch_base::size
virtual size_type size() const =0
Return size of batch.
bm::task_batch_base::~task_batch_base
virtual ~task_batch_base()
Definition bmtask.h:122
bm::task_batch_base::get_task
virtual bm::task_descr * get_task(size_type task_idx)=0
Get task by index in the batch.
bm::task_batch_base::size_type
unsigned size_type
Definition bmtask.h:120
bm::task_batch
Basic implementation for collection of tasks for parallel execution.
Definition bmtask.h:140
bm::task_batch::get_task_vector
task_vector_type & get_task_vector() BMNOEXCEPT
Get access to internal task vector.
Definition bmtask.h:168
bm::task_batch::get_task_vector
const task_vector_type & get_task_vector() const BMNOEXCEPT
Definition bmtask.h:169
bm::task_batch::bv_allocator_type
BVAlloc bv_allocator_type
Definition bmtask.h:142
bm::task_batch::size
virtual size_type size() const BMNOEXCEPT
task_batch_base intreface implementation
Definition bmtask.h:158
bm::task_batch::size_type
task_batch_base::size_type size_type
Definition bmtask.h:143
bm::task_batch::add
void add(task_function_t f, void *argptr)
Definition bmtask.h:172
bm::task_batch::task_vector_type
std::vector< bm::task_descr > task_vector_type
Definition bmtask.h:146
bm::task_batch::get_task
virtual bm::task_descr * get_task(size_type task_idx)
Get task by index in the batch.
Definition bmtask.h:160
bm::task_batch< allocator_type >::task_vect_
task_vector_type task_vect_
Definition bmtask.h:180
bm::task_function_t
std::function< int(void *)> task_function_t
Typedef for a call-back functional for lambda capture.
Definition bmtask.h:54
bm::run_task_batch
void run_task_batch(task_batch_base &tasks)
Run task batch sequentially.
Definition bmtask.h:194
bm
Definition bm.h:78
bm::id64_t
unsigned long long int id64_t
Definition bmconst.h:35
bm::is_lock_noexcept
"noexcept" traits detection for T::lock()
Definition bmtask.h:213
bm::is_lock_noexcept::value
static constexpr bool value
Definition bmtask.h:217
bm::task_descr
BitMagic task with a captured function.
Definition bmtask.h:62
bm::task_descr::task_descr
task_descr(task_function_t f, void *argptr=0) noexcept
Definition bmtask.h:93
bm::task_descr::argp
void * argp
arg pointer
Definition bmtask.h:72
bm::task_descr::done
std::atomic_bool done
0 - pending
Definition bmtask.h:77
bm::task_descr::run
int run()
Definition bmtask.h:103
bm::task_descr::task_descr
task_descr(const task_descr &td)
Definition bmtask.h:84
bm::task_descr::task_flags
task_flags
Definition bmtask.h:64
bm::task_descr::barrier_ok
@ barrier_ok
barrier waits all prev.tasks done without error
Definition bmtask.h:66
bm::task_descr::barrier_ok_delayed
@ barrier_ok_delayed
Definition bmtask.h:68
bm::task_descr::no_flag
@ no_flag
no flag specified
Definition bmtask.h:65
bm::task_descr::barrier_any
@ barrier_any
barrier waits all prev tasks done (success or not)
Definition bmtask.h:67
bm::task_descr::flags
bm::id64_t flags
task flags to designate barriers
Definition bmtask.h:75
bm::task_descr::task_descr
task_descr() BMNOEXCEPT
Definition bmtask.h:82
bm::task_descr::func
task_function_t func
captured function callback
Definition bmtask.h:71
bm::task_descr::init
void init(task_function_t f, void *argptr) noexcept
Definition bmtask.h:98
bm::task_descr::err_code
int err_code
error code
Definition bmtask.h:76