mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-24 15:25:00 +08:00
[svn-r7311] Purpose:
Bug fix Description: Corrected thread-safe error checking tests to use per-thread 'automatic error' callbacks. Also, minor code cleanups Platforms tested: h5committested
This commit is contained in:
parent
6f26af4580
commit
8d120c4d02
@ -47,8 +47,7 @@
|
||||
|
||||
#ifdef H5_HAVE_THREADSAFE
|
||||
|
||||
/*#define NUM_THREAD 16*/
|
||||
#define NUM_THREAD 2
|
||||
#define NUM_THREAD 16
|
||||
#define FILENAME "ttsafe_error.h5"
|
||||
|
||||
/* Having a common dataset name is an error */
|
||||
@ -57,15 +56,15 @@
|
||||
#define WRITE_NUMBER 37
|
||||
|
||||
static herr_t error_callback(hid_t, void *);
|
||||
static herr_t walk_error_callback(int, H5E_error_t *, void *);
|
||||
static herr_t walk_error_callback(unsigned, H5E_error_t *, void *);
|
||||
static void *tts_error_thread(void *);
|
||||
|
||||
/* Global variables */
|
||||
hid_t error_file;
|
||||
|
||||
typedef struct err_num_struct {
|
||||
hid_t maj_num;
|
||||
hid_t min_num;
|
||||
hid_t maj_num;
|
||||
hid_t min_num;
|
||||
} err_num_t;
|
||||
|
||||
err_num_t expected[8];
|
||||
@ -76,173 +75,152 @@ pthread_mutex_t error_mutex;
|
||||
|
||||
void tts_error(void)
|
||||
{
|
||||
pthread_t threads[NUM_THREAD];
|
||||
pthread_attr_t attribute;
|
||||
H5E_auto_t old_error_cb;
|
||||
void *old_error_client_data;
|
||||
hid_t dataset;
|
||||
int value, i;
|
||||
H5E_t *tmp;
|
||||
pthread_t threads[NUM_THREAD];
|
||||
pthread_attr_t attribute;
|
||||
hid_t dataset;
|
||||
int value, i;
|
||||
|
||||
expected[0].maj_num = H5E_DATASET;
|
||||
expected[0].min_num = H5E_CANTINIT;
|
||||
/* Must initialize these at runtime */
|
||||
expected[0].maj_num = H5E_DATASET;
|
||||
expected[0].min_num = H5E_CANTINIT;
|
||||
|
||||
expected[1].maj_num = H5E_DATASET;
|
||||
expected[1].min_num = H5E_CANTINIT;
|
||||
expected[1].maj_num = H5E_DATASET;
|
||||
expected[1].min_num = H5E_CANTINIT;
|
||||
|
||||
expected[2].maj_num = H5E_SYM;
|
||||
expected[2].min_num = H5E_EXISTS;
|
||||
expected[2].maj_num = H5E_SYM;
|
||||
expected[2].min_num = H5E_EXISTS;
|
||||
|
||||
expected[3].maj_num = H5E_SYM;
|
||||
expected[3].min_num = H5E_CANTINSERT;
|
||||
expected[3].maj_num = H5E_SYM;
|
||||
expected[3].min_num = H5E_CANTINSERT;
|
||||
|
||||
expected[4].maj_num = H5E_SYM;
|
||||
expected[4].min_num = H5E_CANTINSERT;
|
||||
expected[4].maj_num = H5E_SYM;
|
||||
expected[4].min_num = H5E_CANTINSERT;
|
||||
|
||||
expected[5].maj_num = H5E_BTREE;
|
||||
expected[5].min_num = H5E_CANTINIT;
|
||||
expected[5].maj_num = H5E_BTREE;
|
||||
expected[5].min_num = H5E_CANTINIT;
|
||||
|
||||
expected[6].maj_num = H5E_BTREE;
|
||||
expected[6].min_num = H5E_CANTINSERT;
|
||||
expected[6].maj_num = H5E_BTREE;
|
||||
expected[6].min_num = H5E_CANTINSERT;
|
||||
|
||||
expected[7].maj_num = H5E_SYM;
|
||||
expected[7].min_num = H5E_CANTINSERT;
|
||||
expected[7].maj_num = H5E_SYM;
|
||||
expected[7].min_num = H5E_CANTINSERT;
|
||||
|
||||
/* set up mutex for global count of errors */
|
||||
pthread_mutex_init(&error_mutex, NULL);
|
||||
/* set up mutex for global count of errors */
|
||||
pthread_mutex_init(&error_mutex, NULL);
|
||||
|
||||
/* preserve previous error stack handler */
|
||||
H5Eget_auto(H5E_DEFAULT, &old_error_cb, &old_error_client_data);
|
||||
fprintf(stderr, "tts_error: error_cb=%p, H5Eprint=%p\n", error_callback, H5Eprint);
|
||||
/* set our own auto error stack handler */
|
||||
H5Eset_auto(H5E_DEFAULT, error_callback, NULL);
|
||||
|
||||
/* make thread scheduling global */
|
||||
pthread_attr_init(&attribute);
|
||||
/* make thread scheduling global */
|
||||
pthread_attr_init(&attribute);
|
||||
#ifdef H5_HAVE_SYSTEM_SCOPE_THREADS
|
||||
pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM);
|
||||
pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM);
|
||||
#endif /* H5_HAVE_SYSTEM_SCOPE_THREADS */
|
||||
|
||||
/*
|
||||
* Create a hdf5 file using H5F_ACC_TRUNC access, default file
|
||||
* creation plist and default file access plist
|
||||
*/
|
||||
error_file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
tmp = pthread_getspecific(H5TS_errstk_key_g);
|
||||
HDfprintf(stderr, "tts_error: tmp=%p, ", tmp);
|
||||
if(tmp)
|
||||
HDfprintf(stderr, "tmp->func=%p\n", tmp->func);
|
||||
/*
|
||||
* Create a hdf5 file using H5F_ACC_TRUNC access, default file
|
||||
* creation plist and default file access plist
|
||||
*/
|
||||
error_file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
||||
|
||||
for (i = 0; i < NUM_THREAD; i++)
|
||||
pthread_create(&threads[i], &attribute, tts_error_thread, NULL);
|
||||
for (i = 0; i < NUM_THREAD; i++)
|
||||
pthread_create(&threads[i], &attribute, tts_error_thread, NULL);
|
||||
|
||||
for (i = 0; i < NUM_THREAD; i++)
|
||||
pthread_join(threads[i],NULL);
|
||||
for (i = 0; i < NUM_THREAD; i++)
|
||||
pthread_join(threads[i],NULL);
|
||||
|
||||
if (error_flag) {
|
||||
fprintf(stderr, "Threads reporting different error values!\n");
|
||||
num_errs++;
|
||||
}
|
||||
if (error_flag) {
|
||||
fprintf(stderr, "Threads reporting different error values!\n");
|
||||
num_errs++;
|
||||
}
|
||||
|
||||
if (error_count != NUM_THREAD - 1) {
|
||||
fprintf(stderr, "Error: %d threads failed instead of %d\n",
|
||||
error_count, NUM_THREAD-1);
|
||||
num_errs++;
|
||||
}
|
||||
if (error_count != NUM_THREAD - 1) {
|
||||
fprintf(stderr, "Error: %d threads failed instead of %d\n", error_count, NUM_THREAD-1);
|
||||
num_errs++;
|
||||
}
|
||||
|
||||
dataset = H5Dopen(error_file, DATASETNAME);
|
||||
H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
|
||||
dataset = H5Dopen(error_file, DATASETNAME);
|
||||
H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
|
||||
|
||||
if (value != WRITE_NUMBER) {
|
||||
fprintf(stderr,
|
||||
"Error: Successful thread wrote value %d instead of %d\n",
|
||||
value, WRITE_NUMBER);
|
||||
num_errs++;
|
||||
}
|
||||
if (value != WRITE_NUMBER) {
|
||||
fprintf(stderr, "Error: Successful thread wrote value %d instead of %d\n", value, WRITE_NUMBER);
|
||||
num_errs++;
|
||||
}
|
||||
|
||||
H5Dclose(dataset);
|
||||
H5Fclose(error_file);
|
||||
H5Dclose(dataset);
|
||||
H5Fclose(error_file);
|
||||
|
||||
/* turn our error stack handler off */
|
||||
H5Eset_auto(H5E_DEFAULT, old_error_cb, old_error_client_data);
|
||||
|
||||
/* Destroy the thread attribute */
|
||||
pthread_attr_destroy(&attribute);
|
||||
/* Destroy the thread attribute */
|
||||
pthread_attr_destroy(&attribute);
|
||||
}
|
||||
|
||||
static
|
||||
void *tts_error_thread(void *arg)
|
||||
void *tts_error_thread(void UNUSED *arg)
|
||||
{
|
||||
hid_t dataspace, datatype, dataset;
|
||||
hsize_t dimsf[1]; /* dataset dimensions */
|
||||
int value;
|
||||
H5E_t *tmp;
|
||||
tmp = pthread_getspecific(H5TS_errstk_key_g);
|
||||
HDfprintf(stderr, "tts_error_thread: tmp=%p, ", tmp);
|
||||
if(tmp)
|
||||
HDfprintf(stderr, "tmp->func=%p\n", tmp->func);
|
||||
/* define dataspace for dataset */
|
||||
dimsf[0] = 1;
|
||||
dataspace = H5Screate_simple(1,dimsf,NULL);
|
||||
hid_t dataspace, datatype, dataset;
|
||||
hsize_t dimsf[1]; /* dataset dimensions */
|
||||
H5E_auto_t old_error_cb;
|
||||
void *old_error_client_data;
|
||||
int value;
|
||||
|
||||
/* define datatype for the data using native little endian integers */
|
||||
datatype = H5Tcopy(H5T_NATIVE_INT);
|
||||
H5Tset_order(datatype, H5T_ORDER_LE);
|
||||
/* preserve previous error stack handler */
|
||||
H5Eget_auto(H5E_DEFAULT, &old_error_cb, &old_error_client_data);
|
||||
|
||||
/* create a new dataset within the file */
|
||||
dataset = H5Dcreate(error_file, DATASETNAME, datatype, dataspace,
|
||||
H5P_DEFAULT);
|
||||
if (dataset >= 0) { /* not an error */
|
||||
value = WRITE_NUMBER;
|
||||
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
||||
H5P_DEFAULT, &value);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
/* set each thread's error stack handler */
|
||||
H5Eset_auto(H5E_DEFAULT, error_callback, NULL);
|
||||
|
||||
H5Tclose(datatype);
|
||||
H5Sclose(dataspace);
|
||||
arg = arg; /* gets rid of annoying warning message */
|
||||
return NULL;
|
||||
/* define dataspace for dataset */
|
||||
dimsf[0] = 1;
|
||||
dataspace = H5Screate_simple(1,dimsf,NULL);
|
||||
|
||||
/* define datatype for the data using native little endian integers */
|
||||
datatype = H5Tcopy(H5T_NATIVE_INT);
|
||||
H5Tset_order(datatype, H5T_ORDER_LE);
|
||||
|
||||
/* create a new dataset within the file */
|
||||
dataset = H5Dcreate(error_file, DATASETNAME, datatype, dataspace, H5P_DEFAULT);
|
||||
if (dataset >= 0) { /* not an error */
|
||||
value = WRITE_NUMBER;
|
||||
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
|
||||
H5Dclose(dataset);
|
||||
}
|
||||
|
||||
H5Tclose(datatype);
|
||||
H5Sclose(dataspace);
|
||||
|
||||
/* turn our error stack handler off */
|
||||
H5Eset_auto(H5E_DEFAULT, old_error_cb, old_error_client_data);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
herr_t error_callback(hid_t estack, void *client_data)
|
||||
{
|
||||
|
||||
fprintf(stderr, "err_cb\n");
|
||||
pthread_mutex_lock(&error_mutex);
|
||||
error_count++;
|
||||
pthread_mutex_unlock(&error_mutex);
|
||||
client_data = client_data; /* gets rid of annoying warning message */
|
||||
return H5Ewalk(estack, H5E_WALK_DOWNWARD, walk_error_callback, NULL);
|
||||
pthread_mutex_lock(&error_mutex);
|
||||
error_count++;
|
||||
pthread_mutex_unlock(&error_mutex);
|
||||
return H5Ewalk(estack, H5E_WALK_DOWNWARD, walk_error_callback, client_data);
|
||||
}
|
||||
|
||||
static
|
||||
herr_t walk_error_callback(int n, H5E_error_t *err_desc, void *client_data)
|
||||
herr_t walk_error_callback(unsigned n, H5E_error_t *err_desc, void UNUSED *client_data)
|
||||
{
|
||||
hid_t maj_num, min_num;
|
||||
fprintf(stderr, "walk_err_cb\n");
|
||||
if (err_desc) {
|
||||
maj_num = err_desc->maj_id;
|
||||
min_num = err_desc->min_id;
|
||||
hid_t maj_num, min_num;
|
||||
|
||||
if (n < EXPECTED_ERROR_DEPTH && maj_num != expected[n].maj_num &&
|
||||
min_num != expected[n].min_num)
|
||||
fprintf(stderr, "walk_err_cb: maj_num=%d, expected[%d].maj=%d, min=%d, expected[%d].min=%d\n",
|
||||
maj_num, n, expected[n].maj_num, min_num, n, expected[n].min_num);
|
||||
if (n < EXPECTED_ERROR_DEPTH && maj_num == expected[n].maj_num &&
|
||||
min_num == expected[n].min_num)
|
||||
return SUCCEED;
|
||||
}
|
||||
if (err_desc) {
|
||||
maj_num = err_desc->maj_id;
|
||||
min_num = err_desc->min_id;
|
||||
|
||||
error_flag = -1;
|
||||
client_data = client_data; /* gets rid of annoying warning message */
|
||||
return SUCCEED;
|
||||
if (n < EXPECTED_ERROR_DEPTH && maj_num == expected[n].maj_num &&
|
||||
min_num == expected[n].min_num)
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
error_flag = -1;
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
void cleanup_error(void)
|
||||
{
|
||||
HDunlink(FILENAME);
|
||||
HDunlink(FILENAME);
|
||||
}
|
||||
|
||||
#endif /*H5_HAVE_THREADSAFE*/
|
||||
|
Loading…
Reference in New Issue
Block a user