mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-09 07:32:32 +08:00
35fe1e2847
were only creating one for all of them). Also changed so that, if they got an error, it actually specifies that the tests failed on the screen instead of succeeded ;-)
176 lines
4.4 KiB
C
176 lines
4.4 KiB
C
/********************************************************************
|
|
*
|
|
* Testing for thread safety in H5A (dataset attribute) library
|
|
* operations. -- Threaded program --
|
|
* ------------------------------------------------------------------
|
|
*
|
|
* Plan: Attempt to break H5Acreate by making many simultaneous create
|
|
* calls.
|
|
*
|
|
* Claim: N calls to H5Acreate should create N attributes for a dataset
|
|
* if threadsafe. If some unprotected shared data exists for the
|
|
* dataset (eg, a count of the number of attributes in the
|
|
* dataset), there is a small chance that consecutive reads occur
|
|
* before a write to that shared variable.
|
|
*
|
|
* HDF5 APIs exercised in thread:
|
|
* H5Acreate, H5Awrite, H5Aclose.
|
|
*
|
|
* Created: Oct 5 1999
|
|
* Programmer: Chee Wai LEE
|
|
*
|
|
* Modification History
|
|
* --------------------
|
|
*
|
|
* 15 May 2000, Chee Wai LEE
|
|
* Incorporated into library tests.
|
|
*
|
|
* 19 May 2000, Bill Wendling
|
|
* Changed so that it creates its own HDF5 file and removes it at cleanup
|
|
* time. Added num_errs flag.
|
|
*
|
|
********************************************************************/
|
|
|
|
#include "ttsafe.h"
|
|
|
|
#ifndef H5_HAVE_THREADSAFE
|
|
static int dummy; /* just to create a non-empty object file */
|
|
#else
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#define FILENAME "ttsafe_acreate.h5"
|
|
#define DATASETNAME "IntData"
|
|
#define NUM_THREADS 16
|
|
|
|
/* Global variables */
|
|
extern int num_errs;
|
|
extern int Verbosity;
|
|
|
|
void *tts_acreate_thread(void *);
|
|
|
|
typedef struct acreate_data_struct {
|
|
hid_t dataset;
|
|
hid_t datatype;
|
|
hid_t dataspace;
|
|
int current_index;
|
|
} ttsafe_name_data_t;
|
|
|
|
void tts_acreate(void)
|
|
{
|
|
/* Pthread declarations */
|
|
pthread_t threads[NUM_THREADS];
|
|
|
|
/* HDF5 data declarations */
|
|
hid_t file, dataset;
|
|
hid_t dataspace, datatype;
|
|
hid_t attribute;
|
|
hsize_t dimsf[1]; /* dataset dimensions */
|
|
|
|
/* data declarations */
|
|
int data; /* data to write */
|
|
int buffer, ret, i;
|
|
|
|
ttsafe_name_data_t *attrib_data;
|
|
|
|
/*
|
|
* Create an HDF5 file using H5F_ACC_TRUNC access, default file
|
|
* creation plist and default file access plist
|
|
*/
|
|
file = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
|
|
|
|
/* create a simple dataspace for the 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(file, DATASETNAME, datatype, dataspace,
|
|
H5P_DEFAULT);
|
|
|
|
/* initialize data for dataset and write value to dataset */
|
|
data = NUM_THREADS;
|
|
H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
|
|
H5P_DEFAULT, &data);
|
|
|
|
/*
|
|
* Simultaneously create a large number of attributes to be associated
|
|
* with the dataset
|
|
*/
|
|
for (i = 0; i < NUM_THREADS; i++) {
|
|
attrib_data = malloc(sizeof(ttsafe_name_data_t));
|
|
attrib_data->dataset = dataset;
|
|
attrib_data->datatype = datatype;
|
|
attrib_data->dataspace = dataspace;
|
|
attrib_data->current_index = i;
|
|
pthread_create(&threads[i], NULL, tts_acreate_thread,
|
|
attrib_data);
|
|
}
|
|
|
|
for (i = 0; i < NUM_THREADS; i++)
|
|
pthread_join(threads[i], NULL);
|
|
|
|
/* verify the correctness of the test */
|
|
for (i = 0; i < NUM_THREADS; i++) {
|
|
attribute = H5Aopen_name(dataset,gen_name(i));
|
|
|
|
if (attribute < 0) {
|
|
fprintf(stderr,
|
|
"unable to open appropriate attribute. "
|
|
"Test failed!\n");
|
|
num_errs++;
|
|
} else {
|
|
ret = H5Aread(attribute, H5T_NATIVE_INT, &buffer);
|
|
|
|
if (ret < 0 || buffer != i) {
|
|
fprintf(stderr,
|
|
"wrong data values. Test failed!\n");
|
|
num_errs++;
|
|
}
|
|
|
|
H5Aclose(attribute);
|
|
}
|
|
}
|
|
|
|
/* close remaining resources */
|
|
H5Sclose(dataspace);
|
|
H5Tclose(datatype);
|
|
H5Dclose(dataset);
|
|
H5Fclose(file);
|
|
}
|
|
|
|
void *tts_acreate_thread(void *client_data)
|
|
{
|
|
hid_t attribute;
|
|
char *attribute_name;
|
|
int *attribute_data; /* data for attributes */
|
|
|
|
ttsafe_name_data_t *attrib_data;
|
|
|
|
attrib_data = (ttsafe_name_data_t *)client_data;
|
|
|
|
/* Create attribute */
|
|
attribute_name = gen_name(attrib_data->current_index);
|
|
attribute = H5Acreate(attrib_data->dataset, attribute_name,
|
|
attrib_data->datatype, attrib_data->dataspace,
|
|
H5P_DEFAULT);
|
|
|
|
/* Write data to the attribute */
|
|
attribute_data = malloc(sizeof(int));
|
|
*attribute_data = attrib_data->current_index;
|
|
H5Awrite(attribute, H5T_NATIVE_INT, attribute_data);
|
|
H5Aclose(attribute);
|
|
return NULL;
|
|
}
|
|
|
|
void cleanup_acreate(void)
|
|
{
|
|
HDunlink(FILENAME);
|
|
}
|
|
|
|
#endif /*H5_HAVE_THREADSAFE*/
|