mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
34d6ef545a
Added new testframe.h header to document testing framework functions and split them away from h5test.h and from test programs that don't integrate with the testframe.c testing framework Added new test setup callback to testframe.c testing framework Added parameters to AddTest() to specify size of test parameters so they can be copied for later use Enabled HDF5 error stacks in testframe.c framework by default and added some error stack suppressions to some testhdf5 tests Added new maxthreads option to testframe.c framework to allow specifying the maximum number of threads a multi-threaded test can use Moved TestExpress functionality out of testframe.c and into more general h5test.c for wider use by tests through getter and setter Updated some tests to not mix and match functionality between h5test.c/h and testframe.c/h Moved some functionality from testphdf5.h into testpar.h for parallel tests that aren't part of testphdf5 Added new parallel test library that contains common shared functionality for parallel tests (similar to h5test library)
180 lines
5.8 KiB
C
180 lines
5.8 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* All rights reserved. *
|
|
* *
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
* the COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/********************************************************************
|
|
*
|
|
* Test the correctness of the thread pool routines
|
|
*
|
|
********************************************************************/
|
|
|
|
#include "ttsafe.h"
|
|
|
|
#ifdef H5_HAVE_THREADS
|
|
|
|
#define NUM_THREADS 16
|
|
|
|
static H5TS_atomic_int_t counter_g;
|
|
|
|
static H5TS_THREAD_RETURN_TYPE
|
|
noop_task(void *_counter)
|
|
{
|
|
H5TS_atomic_int_t *counter = (H5TS_atomic_int_t *)_counter;
|
|
H5TS_thread_ret_t ret_value = 0;
|
|
|
|
VERIFY(H5TS_atomic_load_int(counter), 0, "noop_task");
|
|
|
|
return ret_value;
|
|
}
|
|
|
|
static H5TS_THREAD_RETURN_TYPE
|
|
incr_task(void *_counter)
|
|
{
|
|
H5TS_atomic_int_t *counter = (H5TS_atomic_int_t *)_counter;
|
|
H5TS_thread_ret_t ret_value = 0;
|
|
|
|
H5TS_atomic_fetch_add_int(counter, 1);
|
|
|
|
return ret_value;
|
|
}
|
|
|
|
static H5TS_THREAD_RETURN_TYPE
|
|
decr_task(void *_counter)
|
|
{
|
|
H5TS_atomic_int_t *counter = (H5TS_atomic_int_t *)_counter;
|
|
H5TS_thread_ret_t ret_value = 0;
|
|
|
|
H5TS_atomic_fetch_sub_int(counter, 1);
|
|
|
|
return ret_value;
|
|
}
|
|
|
|
/*
|
|
**********************************************************************
|
|
* tts_atomics
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
void
|
|
tts_atomics(const void H5_ATTR_UNUSED *params)
|
|
{
|
|
H5TS_pool_t *pool = NULL;
|
|
herr_t result;
|
|
|
|
/* Initialize the counter */
|
|
H5TS_atomic_init_int(&counter_g, 0);
|
|
|
|
/* Sanity checks on bad input */
|
|
result = H5TS_pool_create(NULL, NUM_THREADS);
|
|
VERIFY(result, FAIL, "H5TS_pool_create");
|
|
result = H5TS_pool_create(&pool, 0);
|
|
VERIFY(result, FAIL, "H5TS_pool_create");
|
|
result = H5TS_pool_add_task(NULL, noop_task, NULL);
|
|
VERIFY(result, FAIL, "H5TS_pool_add_task");
|
|
result = H5TS_pool_add_task(pool, NULL, NULL);
|
|
VERIFY(result, FAIL, "H5TS_pool_add_task");
|
|
result = H5TS_pool_destroy(NULL);
|
|
VERIFY(result, FAIL, "H5TS_pool_destroy");
|
|
|
|
/* Create & destroy empty pool */
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
/* Create pool, add single 'noop' task, destroy pool */
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
result = H5TS_pool_add_task(pool, noop_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
VERIFY(H5TS_atomic_load_int(&counter_g), 0, "noop");
|
|
|
|
/* Create pool, add single 'incr' task, destroy pool */
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
result = H5TS_pool_add_task(pool, incr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
VERIFY(H5TS_atomic_load_int(&counter_g), 1, "single incr");
|
|
|
|
/* Create pool, add pair of 'incr' & 'decr' tasks, destroy pool */
|
|
H5TS_atomic_store_int(&counter_g, 10);
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
result = H5TS_pool_add_task(pool, incr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
|
|
result = H5TS_pool_add_task(pool, decr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
VERIFY(H5TS_atomic_load_int(&counter_g), 10, "incr + decr");
|
|
|
|
/* Create pool, add many 'incr' & 'decr' tasks, destroy pool */
|
|
H5TS_atomic_store_int(&counter_g, 3);
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
for (unsigned u = 0; u < 200; u++) {
|
|
result = H5TS_pool_add_task(pool, incr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
}
|
|
|
|
for (unsigned u = 0; u < 100; u++) {
|
|
result = H5TS_pool_add_task(pool, decr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
}
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
VERIFY(H5TS_atomic_load_int(&counter_g), 103, "200 incr + 100 decr");
|
|
|
|
/* Create pool, add *lots* of 'incr' & 'decr' tasks, destroy pool */
|
|
H5TS_atomic_store_int(&counter_g, 5);
|
|
result = H5TS_pool_create(&pool, NUM_THREADS);
|
|
CHECK_I(result, "H5TS_pool_create");
|
|
|
|
for (unsigned u = 0; u < 2 * 1000 * 1000; u++) {
|
|
result = H5TS_pool_add_task(pool, incr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
}
|
|
|
|
for (unsigned u = 0; u < 1 * 1000 * 1000; u++) {
|
|
result = H5TS_pool_add_task(pool, decr_task, &counter_g);
|
|
CHECK_I(result, "H5TS_pool_add_task");
|
|
}
|
|
|
|
result = H5TS_pool_destroy(pool);
|
|
CHECK_I(result, "H5TS_pool_destroy");
|
|
|
|
VERIFY(H5TS_atomic_load_int(&counter_g), 5 + (1000 * 1000), "2,000,000 incr + 1,000,000 decr");
|
|
|
|
/* Destroy the atomic counter */
|
|
H5TS_atomic_destroy_int(&counter_g);
|
|
|
|
} /* end tts_atomics() */
|
|
|
|
#endif /* H5_HAVE_THREADS */
|