00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef PALUDIS_GUARD_PALUDIS_UTIL_FORWARD_PARALLEL_FOR_EACH_HH
00021 #define PALUDIS_GUARD_PALUDIS_UTIL_FORWARD_PARALLEL_FOR_EACH_HH 1
00022
00023 #include <paludis/util/mutex.hh>
00024 #include <paludis/util/thread_pool.hh>
00025 #include <tr1/functional>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace paludis
00038 {
00039
00040
00041
00042
00043
00044
00045
00046 template <typename Iter_, typename Func_>
00047 void forward_parallel_for_each_thread_func(Iter_ & cur, const Iter_ & end, Mutex & mutex, Func_ & func,
00048 unsigned n_at_once)
00049 {
00050 while (true)
00051 {
00052 unsigned n_to_do(0);
00053 Iter_ i(end);
00054 {
00055 Lock lock(mutex);
00056 if (cur == end)
00057 return;
00058
00059 i = cur;
00060 while (n_to_do < n_at_once && cur != end)
00061 {
00062 ++cur;
00063 ++n_to_do;
00064 }
00065 }
00066
00067 for (unsigned n(0) ; n < n_to_do ; ++n)
00068 func(*i++);
00069 }
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 template <typename Iter_, typename Func_>
00082 void forward_parallel_for_each(Iter_ cur, const Iter_ & end, Func_ func, unsigned n_threads, unsigned n_at_once)
00083 {
00084 if (cur == end)
00085 return;
00086
00087 Mutex mutex;
00088 ThreadPool threads;
00089
00090 for (unsigned n(0) ; n != n_threads ; ++n)
00091 threads.create_thread(std::tr1::bind(&forward_parallel_for_each_thread_func<Iter_, Func_>, std::tr1::ref(cur),
00092 std::tr1::cref(end), std::tr1::ref(mutex), std::tr1::ref(func), n_at_once));
00093 }
00094 }
00095
00096 #endif