40#ifndef _GLIBCXX_PARALLEL_WORKSTEALING_H 
   41#define _GLIBCXX_PARALLEL_WORKSTEALING_H 1 
   50#define _GLIBCXX_JOB_VOLATILE volatile 
   53  template<
typename _DifferenceTp>
 
   56      typedef _DifferenceTp _DifferenceType;
 
   62      _GLIBCXX_JOB_VOLATILE _DifferenceType 
_M_first;
 
   67      _GLIBCXX_JOB_VOLATILE _DifferenceType 
_M_last;
 
   72      _GLIBCXX_JOB_VOLATILE _DifferenceType 
_M_load;
 
   93  template<
typename _RAIter,
 
  100                                                   _RAIter __end, _Op __op,
 
  109      typedef typename _TraitsType::difference_type _DifferenceType;
 
  113      _DifferenceType __chunk_size =
 
  114          static_cast<_DifferenceType
>(__s.workstealing_chunk_size);
 
  117      _DifferenceType __length = (__bound < 0) ? (__end - __begin) : __bound;
 
  128      omp_lock_t __output_lock;
 
  129      omp_init_lock(&__output_lock);
 
  135      _ThreadIndex __num_threads = __gnu_parallel::max<_ThreadIndex>
 
  136        (1, __gnu_parallel::min<_DifferenceType>(__length,
 
  137                                                 __get_max_threads()));
 
  139#     pragma omp parallel shared(__busy) num_threads(__num_threads) 
  143          __num_threads = omp_get_num_threads();
 
  152        bool __iam_working = 
false;
 
  164        _Result __result = _Result();
 
  167        _DifferenceType __steal;
 
  177        __iam_working = 
true;
 
  180        __my_job.
_M_first = 
static_cast<_DifferenceType
> 
  181          (__iam * (__length / __num_threads));
 
  183        __my_job.
_M_last = (__iam == (__num_threads - 1)
 
  185                            : ((__iam + 1) * (__length / __num_threads) - 1));
 
  192            _DifferenceType __my_first = __my_job.
_M_first;
 
  193            __result = __f(__op, __begin + __my_first);
 
  207#           pragma omp flush(__busy) 
  214                _DifferenceType __current_job =
 
  215                  __fetch_and_add<_DifferenceType>(&(__my_job.
_M_first),
 
  221                for (_DifferenceType __job_counter = 0;
 
  222                     __job_counter < __chunk_size
 
  223                       && __current_job <= __my_job.
_M_last;
 
  227                    __current = __begin + __current_job;
 
  231                    __result = __r(__result, __f(__op, __current));
 
  234#               pragma omp flush(__busy) 
  244                __iam_working = 
false;
 
  247            _DifferenceType __supposed_first, __supposed_last,
 
  253#               pragma omp flush(__busy) 
  254                __victim = __rand_gen();
 
  255                __supposed_first = __job[__victim * __stride].
_M_first;
 
  256                __supposed_last = __job[__victim * __stride].
_M_last;
 
  257                __supposed_load = __job[__victim * __stride].
_M_load;
 
  260                   && ((__supposed_load <= 0)
 
  261                       || ((__supposed_first + __supposed_load - 1)
 
  262                           != __supposed_last)));
 
  267            if (__supposed_load > 0)
 
  271                __steal = (__supposed_load < 2) ? 1 : __supposed_load / 2;
 
  274                _DifferenceType __stolen_first =
 
  275                  __fetch_and_add<_DifferenceType>
 
  276                  (&(__job[__victim * __stride]._M_first), __steal);
 
  277                _DifferenceType __stolen_try = (__stolen_first + __steal
 
  278                                                - _DifferenceType(1));
 
  288                __iam_working = 
true;
 
  290#               pragma omp flush(__busy) 
  292#           pragma omp flush(__busy) 
  295        omp_set_lock(&__output_lock);
 
  296        __output = __r(__output, __result);
 
  297        omp_unset_lock(&__output_lock);
 
  304      __f._M_finish_iterator = __begin + __length;
 
  306      omp_destroy_lock(&__output_lock);
 
Random number generator based on the Mersenne twister. This file is a GNU parallel extension to the S...
End-user include file. Provides advanced settings and tuning options. This file is a GNU parallel ext...
#define _GLIBCXX_CALL(__n)
Macro to produce log message when entering a function.
GNU parallel code for public use.
uint16_t _ThreadIndex
Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit in...
_Op __for_each_template_random_access_workstealing(_RAIter __begin, _RAIter __end, _Op __op, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound)
Work stealing algorithm for random access iterators.
const _Tp & min(const _Tp &__a, const _Tp &__b)
Equivalent to std::min.
void __yield()
Yield control to another thread, without waiting for the end of the time slice.
Traits class for iterators.
Random number generator, based on the Mersenne twister.
class _Settings Run-time settings for the parallel mode including all tunable parameters.
unsigned int cache_line_size
Overestimation of cache line size. Used to avoid false sharing, i.e. elements of different threads ar...
static const _Settings & get()
Get the global settings.
One __job for a certain thread.
volatile _DifferenceType _M_load
Number of elements, i.e. _M_last-_M_first+1.
volatile _DifferenceType _M_last
Last element.
volatile _DifferenceType _M_first
First element.
Compatibility layer, mostly concerned with atomic operations.