forward_parallel_for_each.hh

Go to the documentation of this file.
00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 2009 Ciaran McCreesh
00005  *
00006  * This file is part of the Paludis package manager. Paludis is free software;
00007  * you can redistribute it and/or modify it under the terms of the GNU General
00008  * Public License version 2, as published by the Free Software Foundation.
00009  *
00010  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
00011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013  * details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place, Suite 330, Boston, MA  02111-1307  USA
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 /** \file
00028  * Declarations for the forward_parallel_for_each function.
00029  *
00030  * \ingroup g_threads
00031  *
00032  * \section Examples
00033  *
00034  * - None at this time.
00035  */
00036 
00037 namespace paludis
00038 {
00039     /**
00040      * For forward_parallel_for_each.
00041      *
00042      * \see forward_parallel_for_each
00043      * \since 0.36
00044      * \ingroup g_threads
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      * Like std::for_each, but in parallel, and no return value.
00074      *
00075      * This works for forward iterators, but is only effective if each
00076      * calculation is quite slow.
00077      *
00078      * \since 0.36
00079      * \ingroup g_threads
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

Generated on Mon Sep 21 10:36:08 2009 for paludis by  doxygen 1.5.4