#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <deque>
#include <vector>
#include <set>
#include <rpa/platforms.h>
#include <rpa/algorithms/transform.h>
#include <rpa/testing.h>
Classes | |
struct | ConstChar2StdString |
This functor will be applied to each argument of the command line. More... | |
Defines | |
#define | NB_THR 5 |
Our thread pool. The threads are 'create'-d by the algorithm. | |
#define | NB_SAMPLES ( ( ( 1 << 21 ) + 1 ) * TST_RATIO ) |
Typedefs | |
typedef rpa::testing_mutex | mtx_t |
typedef std::vector< std::string > | VecStrT |
typedef std::back_insert_iterator< VecStrT > | BackInsT |
typedef std::deque< std::string > | DeqStrT |
typedef DeqStrT | DeqStrBufAllocT [NB_THR] |
typedef rpa::range_step< const char *const *, mtx_t > | RngStepT |
typedef rpa::range_step< const char *const *, void > | RngStepAtomT |
Functions | |
template<class Range> | |
static void | t_nobuf_array (VecStrT &myStrVec, size_t aNb, Range aRng) |
template<class Range> | |
static void | t_nobuf_backins (VecStrT &myStrVec, size_t aNb, Range aRng) |
template<class Range> | |
static void | t_nolim_noall (VecStrT &myStrVec, size_t aNb, Range aRng) |
template<class Range> | |
static void | t_nolim_alloc (VecStrT &myStrVec, size_t aNb, Range aRng) |
template<class Range> | |
static void | t_limit_noall (VecStrT &myStrVec, size_t aNb, Range aRng) |
template<class Range> | |
static void | t_limit_alloc (VecStrT &myStrVec, size_t aNb, Range aRng) |
static void | Cmp (int aArgC, const char *const *aArgV, size_t aStep, mtx_t *aMtx, const char *aMsgInfo, void(*aFunc)(VecStrT &, size_t, RngStepT)) |
static void | mainInternMtx (int aArgC, const char *const *aArgV, size_t aStep, mtx_t *aMtx) |
Tests the various output sequences configurations. | |
static void | Cmp (int aArgC, const char *const *aArgV, size_t aStep, const char *aMsgInfo, void(*aFunc)(VecStrT &, size_t, RngStepAtomT)) |
When there is no input mutex, and atomic range_step must be used. | |
static void | mainInternMtx (int aArgC, const char *const *aArgV, size_t aStep) |
Tests the various output sequences configurations. | |
static void | mainIntern (int aArgC, const char *const *aArgV, size_t aStep) |
int | main (int aArgC, const char **aArgV) |
Loops on internal data and on the command line. | |
Variables | |
static rpa::testing_thread * | myThr = NULL |
static mtx_t * | myMtxIn = NULL |
static mtx_t * | myMtxOut = NULL |
static DeqStrBufAllocT | myDeqBuf |
static char | myStr [NB_SAMPLES][RPA_INT_STR] |
Input data for processing. Global data because too big for the stack. | |
static char * | myPtr [NB_SAMPLES] |
#define NB_SAMPLES ( ( ( 1 << 21 ) + 1 ) * TST_RATIO ) |
It is a power of two plus one, because the testing loop multiplies the number of elements by two at each iteration. It is multiplied by a ratio which allows to adjust the tests duration.
#define NB_THR 5 |
Our thread pool. The threads are 'create'-d by the algorithm.
This because we want to use the algorithm 'transform'.
typedef DeqStrT DeqStrBufAllocT[NB_THR] |
Data type for the sub-threads-specific buffers. There is one buffer per sub-thread, therefore this size.
typedef std::deque< std::string > DeqStrT |
Used as a sub-thread-specific buffer : Intermediate results calculated by each sub-thread are stored in such a container.
typedef rpa::testing_mutex mtx_t |
Tests are done with different mutex for the input and the output, but also with the same one, to prove that using the same mutex does not deadlock. A dependency between these two mutexes may happen because the user can use any mutex type. And some external resources may have side effects.
typedef rpa::range_step< const char * const *, void > RngStepAtomT |
typedef rpa::range_step< const char * const *, mtx_t > RngStepT |
typedef std::vector< std::string > VecStrT |
static void Cmp | ( | int | aArgC, | |
const char *const * | aArgV, | |||
size_t | aStep, | |||
const char * | aMsgInfo, | |||
void(*)(VecStrT &, size_t, RngStepAtomT) | aFunc | |||
) | [static] |
When there is no input mutex, and atomic range_step must be used.
static void Cmp | ( | int | aArgC, | |
const char *const * | aArgV, | |||
size_t | aStep, | |||
mtx_t * | aMtx, | |||
const char * | aMsgInfo, | |||
void(*)(VecStrT &, size_t, RngStepT) | aFunc | |||
) | [static] |
int main | ( | int | aArgC, | |
const char ** | aArgV | |||
) |
Loops on internal data and on the command line.
Tests dynamic allocation.
Tries with several step sizes for the dynamic scheduling policy.
An internal number set as a maximum 'reasonable' number.
The number of different values used as steps.
Tries the algorithm with various sizes, smaller and bigger than the number of threads and the size of buffers. At first loop, J=0, then J=1, and for other loops, the number of iterations is multiplied by four.
static void mainIntern | ( | int | aArgC, | |
const char *const * | aArgV, | |||
size_t | aStep | |||
) | [static] |
Run the tests with several mutex for the input :
static void mainInternMtx | ( | int | aArgC, | |
const char *const * | aArgV, | |||
size_t | aStep | |||
) | [static] |
Tests the various output sequences configurations.
static void mainInternMtx | ( | int | aArgC, | |
const char *const * | aArgV, | |||
size_t | aStep, | |||
mtx_t * | aMtx | |||
) | [static] |
Tests the various output sequences configurations.
static void t_limit_alloc | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test with limited-size output buffers. The output is protected by a mutex. The calling program provides a buffers pool, one for sub-thread. 'obuf_iterator' is like 'stdback_inserter', with more parallelization. 'make_thread_tree' creates, out of any threads iterator, a 'thread_tree' object which is necessary for parallel execution.
static void t_limit_noall | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test with limited-size output buffers. The output is protected by a mutex. Each sub-thread allocates its own buffer on the stack. Using the stack has the advantage that we do not need to use 'new', theoretically at least. Which means that if the buffer type is a fixed-size buffer, we can automatically allocate one on the stack - but it is much better to provide these buffers from the program. 'obuf_iterator' is like 'stdback_inserter', with more parallelization. 'make_thread_tree' creates, out of any threads iterator, a 'thread_tree' object which is necessary for parallel execution.
We could test other buffer sizes. This is done in other test programs.
static void t_nobuf_array | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test without output buffer, but with a mutex to protect the output. It writes into a fixed-size array, protected by a mutex.
static void t_nobuf_backins | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test without output buffer, but with a mutex to protect the output. It writes into a back_insert_iterator, protected by a mutex. 'make_thread_tree' creates, out of any threads iterator, a 'thread_tree' object which is necessary for parallel execution.
static void t_nolim_alloc | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test with output buffers of unlimited size : Therefore not output mutex is needed because these mutexes are flushed by the main thread at each 'join'. The calling program provides a buffers pool, one for sub-thread. 'obuf_iterator' is like 'stdback_inserter', with more parallelization. 'make_thread_tree' creates, out of any threads iterator, a 'thread_tree' object which is necessary for parallel execution.
static void t_nolim_noall | ( | VecStrT & | myStrVec, | |
size_t | aNb, | |||
Range | aRng | |||
) | [static] |
Test with output buffers of unlimited size : Therefore not output mutex is needed because these mutexes are flushed by the main thread at each 'join'. 'obuf_iterator' is like 'stdback_inserter', with more parallelization. 'make_thread_tree' creates, out of any threads iterator, a 'thread_tree' object which is necessary for parallel execution.
DeqStrBufAllocT myDeqBuf [static] |
The buffers used by one of the tests. If they are allocated by the calling program, it avoids that each sub-threads creates them on the stack.
char* myPtr[NB_SAMPLES] [static] |
char myStr[NB_SAMPLES][RPA_INT_STR] [static] |
Input data for processing. Global data because too big for the stack.
rpa::testing_thread* myThr = NULL [static] |