mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
7f1e49206d
This is where most people will expect to find license information. The COPYING_LBNL_HDF5 file has also been renamed to LICENSE_LBNL_HDF5. The licenses are unchanged.
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 LICENSE 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 */
|