Commit 2d03b15a authored by Damien Leroux's avatar Damien Leroux
Browse files

Async tasks don't spawn more async tasks now.

parent 4c1779a4
......@@ -13,6 +13,59 @@
#include "cache/md5.h"
#include "cache/file.h"
extern "C" {
#include <dlfcn.h>
#include <malloc.h>
#include <string.h>
}
#include <cxxabi.h>
/*
char*
__cxa_demangle(const char* __mangled_name, char* __output_buffer, size_t* __length, int* __status);
*/
/*using demangle = abi::__cxa_demangle;*/
static inline
std::unordered_map<void*, std::string>&
demangled_names_registry()
{
static std::unordered_map<void*, std::string> _;
return _;
}
template <typename Ret, typename... Args>
std::string&
get_func_name(Ret (*f) (Args...))
{
union {
Ret (*fptr) (Args...);
void* vptr;
} tmp = {f};
std::string& ret = demangled_names_registry()[tmp.vptr];
if (!ret.size()) {
Dl_info info;
dladdr(tmp.vptr, &info);
int status = 0;
char* buf = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
ret.assign(buf, strchr(buf, '('));
free(buf);
/*std::cout << tmp.vptr << " => " << info.dli_sname << std::endl;*/
}
return ret;
}
template <typename Ret, typename... Args>
std::string&
get_func_name(Ret (&f) (Args...))
{
return get_func_name(&f);
}
/* forward */ struct md5_digest;
template <typename X> struct clean_type { typedef typename std::remove_reference<X>::type type; };
......@@ -21,7 +74,7 @@ template <typename X> struct clean_type<X&> { typedef X type; };
template <typename X> struct clean_type<const X> { typedef X type; };
static inline std::string& cache_directory() { static std::string _ = "tmp"; return _; }
static inline std::string& cache_directory() { return active_settings->work_directory; }
template <typename T> struct generic_value_interface;
template <typename T> struct value;
......@@ -99,6 +152,8 @@ template <typename T>
bool valid() const { return (bool) m_impl; }
operator bool () const { return valid(); }
bool equal(const value<T>& v) const { return m_impl == v.m_impl || m_impl->equal(*v.m_impl); }
protected:
......@@ -162,6 +217,20 @@ template <typename Functor, typename Elem, typename... Elems>
};
struct reduce {
template <typename Functor>
auto operator () (typename Functor::accum_type accum, Functor&)
-> typename Functor::accum_type
{
return accum;
}
template <typename Functor>
auto operator () (Functor&)
-> typename Functor::accum_type
{
return typename Functor::accum_type();
}
template <typename Functor, typename... Elems>
auto operator () (typename Functor::accum_type accum, Functor& f, const Elems&... e)
-> typename Functor::accum_type
......@@ -323,16 +392,17 @@ template <typename Ret, typename... Args>
const value<typename clean_type<Args>::type>&... args)
: dependencies(args...)
, m_storage()
/*, m_future(task_type(func, *args...).get_future())*/
, m_future(std::async(func, *args...))
, m_future(active_settings->enqueue(func, *args...))
/*, m_future(std::async(std::launch::async, func, *args...))*/
/*, m_future(std::async(std::launch::deferred, func, *args...))*/
{}
async_computation(std::function<Ret(Args...)>& func,
const value<typename clean_type<Args>::type>&... args)
: dependencies(args...)
, m_storage()
/*, m_future(task_type(func, *args...).get_future())*/
, m_future(std::async(func, *args...))
, m_future(active_settings->enqueue(func, *args...))
/*, m_future(std::async(func, *args...))*/
{}
value_type& __get_noconst()
......@@ -458,9 +528,9 @@ template <typename Ret, typename... Args>
typedef Ret value_type;
typedef std::function<Ret(Args...)> computation_type;
cached_computed_value(const std::string& name, Ret (*func) (Args...), const value<Args>&... args)
cached_computed_value(Ret (*func) (Args...), const value<Args>&... args)
: m_hash(compute_hash(args...))
, m_comp(name, func, args...)
, m_comp(get_func_name(func), func, args...)
, m_comp_proxy([this](Args... x) { return m_comp(x...); })
, m_task(m_comp_proxy, args...)
{}
......@@ -604,49 +674,83 @@ template <typename VT>
using clean_value_type = value<typename clean_type<VT>::type>;
enum CachingPolicy : int { oneshot = 0, mem = 1, disk = 2, mem_and_disk = 3 };
template <typename Ret, typename... Args>
/*computed_value<Ret(Args...)>**/
value<Ret>&
make_value(Ret (&f) (Args...), const value<typename clean_type<Args>::type>&... x)
{
auto& _reg_ = __get_registry<Ret, Args...>();
/*return new computed_value<Ret(Args...)>(&f, x...);*/
value<Ret>& ret = _reg_.get(&f, x...);
if (!ret.valid()) {
/*MSG_INFO("New computed value reg.size=" << (_reg_.size()));*/
ret = new computed_value<Ret(Args...)>(f, x...);
} else {
/*MSG_INFO("Existing computed value reg.size=" << (_reg_.size()));*/
}
return ret;
}
struct with_disk_cache_traits {
typedef cached_computed_value<Ret(Args...)> type;
};
template <typename Ret, typename... Args>
value<Ret>&
make_cached_value_impl(const std::string& name, Ret (&f) (Args...), const clean_value_type<Args>&... x)
{
/*static computation_registry<value<Ret>, Ret (*) (Args...), value<Args>...> _reg_;*/
/*return new cached_computed_value<Ret(Args...)>(name, &f, x...);*/
/*value<Ret>& ret = _reg_.get(&f, x...);*/
value<Ret>& ret = __get_registry<Ret, Args...>().get(&f, x...);
if (!ret.valid()) {
MSG_INFO("New cached computed value");
ret = new cached_computed_value<Ret(Args...)>(name, f, x...);
} else {
MSG_INFO("Existing cached computed value");
}
return ret;
}
struct without_disk_cache_traits {
typedef computed_value<Ret(Args...)> type;
};
template <int _Policy, typename Ret, typename... Args>
struct disk_cache_traits;
#define make_cached_value(__fname, ...) make_cached_value_impl(#__fname, __fname ,##__VA_ARGS__)
template <typename Ret, typename... Args>
struct disk_cache_traits<oneshot, Ret, Args...> : without_disk_cache_traits<Ret, Args...> {};
template <typename Ret, typename... Args>
struct disk_cache_traits<disk, Ret, Args...> : with_disk_cache_traits<Ret, Args...> {};
template <typename Ret, typename... Args>
struct with_mem_cache_traits {
typedef value<Ret>& return_type;
template <typename _Maker>
static
return_type
create(Ret (&f) (Args...), const clean_value_type<Args>&... x)
{
/*MSG_DEBUG("new value with mem cache");*/
return_type ret = __get_registry<Ret, Args...>().get(&f, x...);
if (!ret.valid()) {
ret = new _Maker(f, x...);
}
return ret;
}
};
template <typename Ret, typename... Args>
struct without_mem_cache_traits {
typedef value<Ret> return_type;
template <typename _Maker>
static
return_type
create(Ret (&f) (Args...), const clean_value_type<Args>&... x)
{
/*MSG_DEBUG("new value without mem cache");*/
return_type ret = new _Maker(f, x...);
return ret;
}
};
template <int _Policy, typename Ret, typename... Args>
struct mem_cache_traits;
template <typename Ret, typename... Args>
struct mem_cache_traits<oneshot, Ret, Args...> : without_mem_cache_traits<Ret, Args...> {};
template <typename Ret, typename... Args>
struct mem_cache_traits<mem, Ret, Args...> : with_mem_cache_traits<Ret, Args...> {};
template <CachingPolicy _Policy = oneshot, typename Ret, typename... Args>
typename mem_cache_traits<_Policy & mem, Ret, Args...>::return_type
make_value(Ret (&f) (Args...), const clean_value_type<Args>&... x)
{
typedef mem_cache_traits<_Policy & mem, Ret, Args...> mem_policy;
typedef disk_cache_traits<_Policy & disk, Ret, Args...> disk_policy;
return mem_policy::template create<typename disk_policy::type>(f, x...);
}
template <typename T> struct collection : std::vector<value<T>> {
using std::vector<value<T>>::vector;
};
template <typename F, typename R, typename P> struct make_coll_impl;
template <CachingPolicy C, typename F, typename R, typename P> struct make_coll_impl;
template <typename A, typename B> struct types_must_be_identical : std::integral_constant<bool, false> {};
template <> struct types_must_be_identical<int, double> : std::integral_constant<bool, false> {};
......@@ -665,30 +769,30 @@ template <typename A0, typename... A, typename B0, typename... B>
static_assert(types_must_be_identical<A0, B0>::value, "INVALID PARAMETER TYPE.");
};
template <typename Ret, typename... FuncArgs, typename... ErrArgs>
struct make_coll_impl<Ret(FuncArgs...), std::tuple<>, std::tuple<ErrArgs...>> {
template <CachingPolicy _Policy, typename Ret, typename... FuncArgs, typename... ErrArgs>
struct make_coll_impl<_Policy, Ret(FuncArgs...), std::tuple<>, std::tuple<ErrArgs...>> {
void operator () (collection<Ret>& coll,
Ret (&f) (FuncArgs...),
ErrArgs... errargs)
{
type_lists_must_be_identical<std::tuple<FuncArgs...>, std::tuple<typename ErrArgs::value_type...>>();
coll.push_back(make_value(f, errargs...));
coll.push_back(make_value<_Policy>(f, errargs...));
}
};
template <typename Ret, typename... FuncArgs>
struct make_coll_impl<Ret(FuncArgs...), std::tuple<>, std::tuple<clean_value_type<FuncArgs>...>> {
template <CachingPolicy _Policy, typename Ret, typename... FuncArgs>
struct make_coll_impl<_Policy, Ret(FuncArgs...), std::tuple<>, std::tuple<clean_value_type<FuncArgs>...>> {
void operator () (collection<Ret>& coll,
Ret (&f) (FuncArgs...),
const value<typename clean_type<FuncArgs>::type>&... pargs)
{
coll.push_back(make_value(f, pargs...));
coll.push_back(make_value<_Policy>(f, pargs...));
}
};
template <typename Ret, typename... FuncArgs, typename VT, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<Ret(FuncArgs...), std::tuple<value<VT>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
template <CachingPolicy _Policy, typename Ret, typename... FuncArgs, typename VT, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<_Policy, Ret(FuncArgs...), std::tuple<value<VT>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
void operator () (collection<Ret>& coll,
Ret (&f) (FuncArgs...),
const value<VT>& car,
......@@ -696,14 +800,15 @@ struct make_coll_impl<Ret(FuncArgs...), std::tuple<value<VT>, ArgsRemaining...>,
const PreviousArgs&... pargs)
{
make_coll_impl<
_Policy,
Ret(FuncArgs...),
std::tuple<ArgsRemaining...>,
std::tuple<PreviousArgs..., value<VT>>>() (coll, f, cdr..., pargs..., car);
}
};
template <typename Ret, typename... FuncArgs, typename T, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<Ret(FuncArgs...), std::tuple<range<T>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
template <CachingPolicy _Policy, typename Ret, typename... FuncArgs, typename T, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<_Policy, Ret(FuncArgs...), std::tuple<range<T>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
void operator () (collection<Ret>& coll,
Ret (&f) (FuncArgs...),
const range<T>& car,
......@@ -713,6 +818,7 @@ struct make_coll_impl<Ret(FuncArgs...), std::tuple<range<T>, ArgsRemaining...>,
typedef value<T> vtype;
for (const vtype& v: car) {
make_coll_impl<
_Policy,
Ret(FuncArgs...),
std::tuple<ArgsRemaining...>,
std::tuple<PreviousArgs..., vtype>>() (coll, f, cdr..., pargs..., v);
......@@ -720,8 +826,8 @@ struct make_coll_impl<Ret(FuncArgs...), std::tuple<range<T>, ArgsRemaining...>,
}
};
template <typename Ret, typename... FuncArgs, typename T, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<Ret(FuncArgs...), std::tuple<collection<T>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
template <CachingPolicy _Policy, typename Ret, typename... FuncArgs, typename T, typename... ArgsRemaining, typename... PreviousArgs>
struct make_coll_impl<_Policy, Ret(FuncArgs...), std::tuple<collection<T>, ArgsRemaining...>, std::tuple<PreviousArgs...>> {
void operator () (collection<Ret>& coll,
Ret (&f) (FuncArgs...),
const collection<T>& car,
......@@ -731,6 +837,7 @@ struct make_coll_impl<Ret(FuncArgs...), std::tuple<collection<T>, ArgsRemaining.
typedef value<T> vtype;
for (const vtype& v: car) {
make_coll_impl<
_Policy,
Ret(FuncArgs...),
std::tuple<ArgsRemaining...>,
std::tuple<PreviousArgs..., vtype>>() (coll, f, cdr..., pargs..., v);
......@@ -740,12 +847,12 @@ struct make_coll_impl<Ret(FuncArgs...), std::tuple<collection<T>, ArgsRemaining.
template <typename Ret, typename... Args, typename... CollArgs>
template <CachingPolicy _Policy = oneshot, typename Ret, typename... Args, typename... CollArgs>
collection<Ret>
make_collection(Ret (&f) (Args...), CollArgs... args)
{
collection<Ret> ret;
make_coll_impl<Ret(Args...), std::tuple<CollArgs...>, std::tuple<>>() (ret, f, args...);
make_coll_impl<_Policy, Ret(Args...), std::tuple<CollArgs...>, std::tuple<>>() (ret, f, args...);
return ret;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment