#include <pthread.h>
#include <iterator>
#include <vector>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include <numeric>
#include <set>
#include <list>
#include <deque>
#include <rpa/architectures/posix.h>
#include <rpa/algorithms/accumulate.h>
#include <rpa/algorithms/transform.h>
#include <rpa/containers/list.h>
#include <rpa/containers/deque.h>
#include <rpa/containers/vector.h>
#include <rpa/containers/pipeline.h>
Classes | |
struct | identity26< Type > |
Defines | |
#define | Test(a) _Test26(#a,a) |
Typedefs | |
typedef rpa::posix_condition | cond_main_t |
Used everywhere. | |
typedef rpa::posix_mutex | mutex_lock_type |
This is used each time several threads write into the same iterator. | |
Functions | |
template<class OutIter> | |
void | split (const string &refStr, OutIter outIter) |
Splits a string based on a delimiter. | |
static bool | CmpDelim (const string &strA, const string &strB) |
Compares two strings made of sub-strings separated by spaces. | |
static void | _Test26 (const char *aMsg, bool aBool) |
Simple comparison and display of a message, for debugging. | |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26OneSubThr (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc) |
Only one subthread for the input algorithm. | |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26OneSubThrRange (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26OutputInSubThr (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26ConstPipeAccumRng (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26CopyRangeToCont (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t nbStps) |
This tests checks that elements can be read only once from a pipe line. | |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26CopyRangeToArc (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
This tests checks that elements can be read only once from a pipe line. | |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26MergeDynamic (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26MergeDynamicAsym (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t szPipCirc, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26MonoCircular (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t nbStps) |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26MonoArchiver (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t nbStps) |
Simply reads from a pipe_archiver into a plain container. | |
template<class SubThr, class Container, class PipTyp> | |
static void | tst26DualArchiver (const Container &lstDat, typename Container::value_type sumDat, size_t nbDbls, size_t nbThrs, size_t nbStps) |
template<class SubThr, class Cont, class PipTyp> | |
static void | tst26ContBuf (const Cont &lstDat, typename Cont::value_type sumDat, size_t nbDbls, size_t nbThrs) |
template<class SubThr, class Cont> | |
static void | tst26Containers (size_t nbDbls, size_t nbThrs) |
At init time, a space ios added for further splitting and comparing. | |
template<class SubThr> | |
void | tst26Thr (size_t nbE, size_t nbThrs) |
int | main (int aArgC, const char **aArgV) |
Variables | |
static const char | chrDelim = ' ' |
The delimiter between the substrings, results of concatenations. |
#define Test | ( | a | ) | _Test26(#a,a) |
typedef rpa::posix_condition cond_main_t |
Used everywhere.
typedef rpa::posix_mutex mutex_lock_type |
This is used each time several threads write into the same iterator.
static void _Test26 | ( | const char * | aMsg, | |
bool | aBool | |||
) | [static] |
Simple comparison and display of a message, for debugging.
static bool CmpDelim | ( | const string & | strA, | |
const string & | strB | |||
) | [static] |
Compares two strings made of sub-strings separated by spaces.
int main | ( | int | aArgC, | |
const char ** | aArgV | |||
) |
void split | ( | const string & | refStr, | |
OutIter | outIter | |||
) |
Splits a string based on a delimiter.
static void tst26ConstPipeAccumRng | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
We build first a circular pipeline which is constant, and big enough to contain all input data. And later run on it 'accumulate' which reads range of data.
This pipeline is shut at the beginning. It means that a reading thread will detect the end of the pipeline.
This checks that the init value is correct. The space is for splitting.
Execution of this functor, which now waits until its subthreads finished. They do not need to wait for the input pipeline which is full and shut.
This waits for the final result. This is a blocking call until the thread is 'joined'. A thread is created for running the algorithm, and this thread may create sub-threads.
We do not print the resulting string which may be very long.
static void tst26Containers | ( | size_t | nbDbls, | |
size_t | nbThrs | |||
) | [static] |
At init time, a space ios added for further splitting and comparing.
First, creates a container with the natural order of strings.
static void tst26ContBuf | ( | const Cont & | lstDat, | |
typename Cont::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs | |||
) | [static] |
static void tst26CopyRangeToArc | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
This tests checks that elements can be read only once from a pipe line.
The output pipe may have another type of underlying container. The output pipes have a limit.
A back_insert_iterator into a pipeline is protected because the method push_back() is thread_safe. Therefore, it is not necessary to protect it with a mutex.
This functor will be started in a subthread.
A shutter_thread sets the pipe as closed at the end of the thread. So, the reader know that no other data will come from this pipe, and then they stop waiting.
The output elements might not be in the right order. So we sort them before comparing. This happens if there are genuine subthreads.
We must reorder the original input data which is in the order of integer numbers, not strings.
static void tst26CopyRangeToCont | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | nbStps | |||
) | [static] |
This tests checks that elements can be read only once from a pipe line.
A shutter_thread sets the pipe as closed at the end of the thread. So, the reader know that no other data will come from this pipe, and then they stop waiting. The insertion into the container is not protected because it will be executed without subthreads.
There is the thread tree containing just one top-level sub-thread. Therefore, it is not necessary to lock the insertion iterator into the container, because just one will write into it at a time.
This functor will be started in a subthread.
This starts the algorithm in a thread tree which has just a thread at its head.
It waits until the end of the algorithm. The output container must NOT be used until the end, because it is not protected by a mutex.
These containers must be identical.
static void tst26DualArchiver | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | nbStps | |||
) | [static] |
This tests checks that elements can be read only once from a pipe line. The input elements must absolutely be sorted.
Two different ranges are reading the same input This functor will be started in a subthread.
This functor will be started in a subthread.
We wait until the sub-threads are finished, otherwise the size would be meaningless. The output pipes must be limitless to contain the whole output.
We must reorder the original input data which is in the order of integer numbers, not strings.
These containers must be identical.
static void tst26MergeDynamic | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
This tests checks that elements can be read only once from a pipe line. Two different threads read the same pipe_circular, with ranges. The input elements must absolutely be sorted.
The output pipe may have another type of underlying container. The output pipes have a limit.
Two different ranges are reading the same input. This functor will be started in a subthread.
A shutter_thread sets the pipe as closed at the end of the thread. So, the readers know that no other data will come from this pipe, and then they stop waiting.
This functor will be started in a subthread.
There may be several sub-threads and therefore the results have a changed order.
This is computed before waiting the end of the subthreads.
We must reorder the original input data which is in the order of integer numbers, not strings.
These containers must be identical.
static void tst26MergeDynamicAsym | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
This tests checks that elements can be read only once from a pipe line. Two threads read the same pipe. One of them uses a range, the other reads the elements one after the other. The input elements must absolutely be sorted.
The output pipe may have another type of underlying container. The output pipes have a limit.
Two different ranges are reading the same input. This functor will be started in a subthread. The elements are read slice by slice.
A shutter_thread sets the pipe as closed at the end of the thread. So, the readers know that no ther data will come from this pipe, and then they stop waiting.
The output pipe must be able to store all elements otherwise it would hang forever, because the last reading call runs in the same thread.
This functor is run in the same thread. It does not matter if it starves, because the subthread will read from the input pipe too. The elements are read one after the other.
This is computed before waiting the end of the subthreads.
We must reorder the original input data which is in the order of integer numbers, not strings.
These containers must be identical.
static void tst26MonoArchiver | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | nbStps | |||
) | [static] |
Simply reads from a pipe_archiver into a plain container.
This pipe is initially shut. We will read its content and will not wait when it will be empty. There is no write access during the reads.
The type of the main thread running the algorithm which reads the input pipe.
The output iterator must be protected because several sub-threads will write into it. The mutex can have any type and is independent of the mutex locking read accesses from the pipeline.
The output container must be limitless to contain the whole data.
Two different ranges are reading the same input This functor will be started in a subthread.
The algorithm which reads the input data slices by slices (And not element by element, hence the range_step_type).
We wait until the sub-threads are finished, otherwise the size would be meaningless.
We must reorder the original input data which is in the order of integer numbers, not strings.
These containers must be identical.
static void tst26MonoCircular | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | nbStps | |||
) | [static] |
Simply reads from a pipe_circular into a plain container. This is basically the same as tst26MonoArchiver except that a circular is used instead of an archiver.
This pipe is initially shut. We will read its content and will not wait when it will be empty. There is no write access during the reads.
The output iterator must be protected because several sub-threads will write into it. The mutex can have any type and is independent of the mutex locking read accesses from the pipeline.
The output container must be limitless to contain the whole data.
Two different ranges are reading the same input This functor is started in the main thread. It starts its sub-threads.
This will exit when the result will be computed. The algorithm reads the input data slices by slices (And not element by element, hence the range_step_type).
Using sets is necessary because several threads may insert the elements in a different order.
These containers must be identical.
static void tst26OneSubThr | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc | |||
) | [static] |
Only one subthread for the input algorithm.
The buffer is not big enough to store all the input data, but the main thread is running at the same time and reads from it.
Finite-size pipeline. There may not be enough room for the result of 'transform'.
static void tst26OneSubThrRange | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
Only one subthread for the input algorithm. The buffer is not big enough to store all the input data, but the main thread is running at the same time and reads from it.
Finite-size pipeline. There may not be enough room to store the result of the 'transform'algorithm.
static void tst26OutputInSubThr | ( | const Container & | lstDat, | |
typename Container::value_type | sumDat, | |||
size_t | nbDbls, | |||
size_t | nbThrs, | |||
size_t | szPipCirc, | |||
size_t | nbStps | |||
) | [static] |
This test is composed of a 'transform' algorithm, whose output is piped (circular-pipe) into a 'accumulate' algorithm. The accumulate algorithm runs in a sub-thread. The transform algorithm runs in a sub-thread too, which shuts the pipe at its end.
This pipeline is not shut at the beginning. It means that a reading thread will hang, until it is shut or not empty.
Now this sub-thread is waiting for data to be written in the pipe.
Waits for the result. This is a blocking call until the thread is joined.
void tst26Thr | ( | size_t | nbE, | |
size_t | nbThrs | |||
) |
There are two imbricated loop on the containers type. The external container type is always limit-less. The internal one may have a limit and will therefore never used for infinite pipelines.
const char chrDelim = ' ' [static] |
The delimiter between the substrings, results of concatenations.