rpa::range_step< It, void > Class Template Reference

#include <common.h>

Inheritance diagram for rpa::range_step< It, void >:

rpa::range_step_base< It > List of all members.

Public Types

typedef atomic< It > atom_it
typedef It iterator
typedef std::iterator_traits<
It >::value_type 
value_type
typedef range_step_base< It
>::slice 
slice

Public Member Functions

iterator begin (void) const
const iterator end (void) const
size_t size_safe (void) const
 For debugging. Returns an 'absurd' value if the iterators are 'output_type'.
 range_step (const range_step &aRS)
 Plain copy constructor. Same as the compiler-generated copy ctor (To remove ???).
 range_step (It aBeg, It aEnd, size_t aStep=StepUndef, chunk_t aMinChkSz=chunk_t())
 This constructor allows to choose exactly the value of the step.
 range_step (It aBeg, It aEnd, chunk_t aMinChkSz=chunk_t())
 If the 'step' of each sequential execution is not given, it gets the default value.
slice chop (void)
size_t chop_again (slice &refSlice)
template<class Rng2>
size_t chop_again (tuple2< slice, typename Rng2::slice > &aPairRef, Rng2 &aSq2)
template<class Rng2>
tuple2< slice, typename Rng2::slice > chop_init_lock (Rng2 &aSq2)
template<class Rng2>
tuple2< slice, typename Rng2::slice > chop_init_nolock (Rng2 &aSq2)
slice chop_init_lock_cond (bool)
template<class Rng2>
tuple2< slice, typename Rng2::slice > chop_init_lock_cond (Rng2 &aSq2, bool mustLock)

Private Member Functions

 range_step ()
range_stepoperator= (const range_step &)

Private Attributes

atom_it::atomic_type _RngBeg
const It _RngEnd

Classes

struct  chop_atom_t
struct  chop_atom_t< range_outp< obuf_iterator< IterOut, Buffer, IterBuf, Mutex > > >
struct  range_out
struct  range_out< It2, std::bidirectional_iterator_tag >
 For exemple, if we write into an output sequence which is already allocated. More...
struct  range_out< It2, std::forward_iterator_tag >
struct  range_out< It2, std::random_access_iterator_tag >
struct  range_out< iterator_lock< It2, Mutex >, std::bidirectional_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< iterator_lock< It2, Mutex >, std::forward_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< iterator_lock< It2, Mutex >, std::input_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< iterator_lock< It2, Mutex >, std::output_iterator_tag >
 For the moment, just to compile, and reuse the defaut existing range_out. More...
struct  range_out< iterator_lock< It2, Mutex >, std::random_access_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< obuf_iterator< IterOut, Buffer, IterBuf, Mutex >, std::bidirectional_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< obuf_iterator< IterOut, Buffer, IterBuf, Mutex >, std::forward_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< obuf_iterator< IterOut, Buffer, IterBuf, Mutex >, std::input_iterator_tag >
 This template specialization, to forbid this case to happen. More...
struct  range_out< obuf_iterator< IterOut, Buffer, IterBuf, Mutex >, std::output_iterator_tag >
struct  range_out< obuf_iterator< IterOut, Buffer, IterBuf, Mutex >, std::random_access_iterator_tag >
 This template specialization, to forbid this case to happen. More...
class  range_type_iterator_lock
 This to avoid an ambiguous template instantiation. More...

Detailed Description

template<class It>
class rpa::range_step< It, void >

This is a range for dynamic scheduling, with a fixed number of elements (the step) taken for calculation by each sub-thread when it is idle. No mutex, because we assume that the input iterator is atomic, thread-safe. Of course, this is not possible in the general case, and can be done only of the input containers have atomic capabilities.


Member Typedef Documentation

template<class It>
typedef atomic< It > rpa::range_step< It, void >::atom_it

About the same as 'range_lambda', but we must be able to read atomically the beginning of the sequence. Therefore, this beginning is encapsulated.

template<class It>
typedef It rpa::range_step< It, void >::iterator

template<class It>
typedef range_step_base< It >::slice rpa::range_step< It, void >::slice

template<class It>
typedef std::iterator_traits< It >::value_type rpa::range_step< It, void >::value_type


Constructor & Destructor Documentation

template<class It>
rpa::range_step< It, void >::range_step (  )  [private]

template<class It>
rpa::range_step< It, void >::range_step ( const range_step< It, void > &  aRS  )  [inline]

Plain copy constructor. Same as the compiler-generated copy ctor (To remove ???).

template<class It>
rpa::range_step< It, void >::range_step ( It  aBeg,
It  aEnd,
size_t  aStep = StepUndef,
chunk_t  aMinChkSz = chunk_t() 
) [inline]

This constructor allows to choose exactly the value of the step.

template<class It>
rpa::range_step< It, void >::range_step ( It  aBeg,
It  aEnd,
chunk_t  aMinChkSz = chunk_t() 
) [inline]

If the 'step' of each sequential execution is not given, it gets the default value.


Member Function Documentation

template<class It>
iterator rpa::range_step< It, void >::begin ( void   )  const [inline]

template<class It>
slice rpa::range_step< It, void >::chop ( void   )  [inline]

Maybe other synchronization possibilities.

This picks up on the two ranges (Input and output ranges), 'slices' of data to be given to a sub-thread. The difficulty here is that we have to take these slices in an atomic manner. Just as the Motorola instruction CAS2 (Compare and swap on two memory words) works. So, this may not work on first try, and we have to loop until the CompareAndSwap is successful.

The read access must be atomic, because of the other sub-threads.

In the mean time, '_RngBeg' may have changed.

This is why we use CompareAndSwap.

template<class It>
template<class Rng2>
size_t rpa::range_step< It, void >::chop_again ( tuple2< slice, typename Rng2::slice > &  aPairRef,
Rng2 &  aSq2 
) [inline]

This picks up on the two ranges (Input and output ranges), 'slices' of data to be given to a sub-thread. The difficulty here is that we have to take these slices the atomic way. Just like the Motorola instruction CAS2 (Compare and swap on two memory words) used to work. So, this may not work on first try, and we have to loop until the CompareAndSwap is successful.

Do not reuse '_RngBeg' which may have changed in the mean time, because of another subthread : For 'range_step', the input sequence is 'write-shared' by all subthreads. This is why we use an atomic 'load'.

template<class It>
size_t rpa::range_step< It, void >::chop_again ( slice refSlice  )  [inline]

Does the same as 'chop' but the slice is reused and its destructor is not called - which is the goal: NOTE: Temporary sub-optimal solution.

The read access must be atomic, because of the other sub-threads.

In the mean time, '_RngBeg' may have changed.

This is why we use CompareAndSwap.

template<class It>
template<class Rng2>
tuple2< slice, typename Rng2::slice > rpa::range_step< It, void >::chop_init_lock ( Rng2 &  aSq2  )  [inline]

template<class It>
template<class Rng2>
tuple2< slice, typename Rng2::slice > rpa::range_step< It, void >::chop_init_lock_cond ( Rng2 &  aSq2,
bool  mustLock 
) [inline]

Called only by the constructor of 'coroutine_step', that is, the object used as a functor for each sub-thread. Therefore, we are sure that this constructor is called by the main thread, sequentially. Anyway, as long as the first sub-thread is created, we must lock the input range.

template<class It>
slice rpa::range_step< It, void >::chop_init_lock_cond ( bool   )  [inline]

Called only by the constructor of 'coroutine_step', that is, the object used as a functor for each sub-thread. Therefore, we are sure that this constructor is called by the main thread, sequentially. Anyway, as long as the first sub-thread is created, we must lock the input range. TODO: It always locks, this should be optimised.

template<class It>
template<class Rng2>
tuple2< slice, typename Rng2::slice > rpa::range_step< It, void >::chop_init_nolock ( Rng2 &  aSq2  )  [inline]

template<class It>
const iterator rpa::range_step< It, void >::end ( void   )  const [inline]

template<class It>
range_step& rpa::range_step< It, void >::operator= ( const range_step< It, void > &   )  [private]

template<class It>
size_t rpa::range_step< It, void >::size_safe ( void   )  const [inline]

For debugging. Returns an 'absurd' value if the iterators are 'output_type'.


Member Data Documentation

template<class It>
atom_it::atomic_type rpa::range_step< It, void >::_RngBeg [private]

template<class It>
const It rpa::range_step< It, void >::_RngEnd [private]


The documentation for this class was generated from the following file:
Generated on Tue Sep 25 10:20:36 2007 for rpa by  doxygen 1.4.7