Hi Quincey,
On 6/28/2011 6:32 AM, Quincey Koziol wrote:
Hi Matt,
On Jun 27, 2011, at 11:49 AM, Matthew Chambers wrote:
Due to the C++ bindings not being thread-safe, I was hoping to turn off
thread-safety in the C core and handle synchronization in my code. This turned
out to be impossible because the HDF5 core uses global, non-thread-specific
data structures when H5_HAVE_THREADSAFE is undefined. There does not appear to
be a way to turn off internal synchronization while keeping thread or instance
specific data structures. That would be useful. SQLite has good semantics for
thread safety:
http://www.sqlite.org/compile.html#threadsafe
This option controls whether or not code is included in SQLite to enable it to
operate safely in a multithreaded environment. The default is
SQLITE_THREADSAFE=1 which is safe for use in a
multithreaded environment. When compiled with SQLITE_THREADSAFE=0 all mutexing
code is omitted and it is unsafe to use SQLite in a multithreaded program. When
compiled with
SQLITE_THREADSAFE=2, SQLite can be used in a multithreaded program so long as
no two threads
attempt to use the same database connection at the same time.
At the very least it would be useful if the documentation specifies that
H5_HAVE_THREADSAFE controls both the use of global data structures and
synchronization. I had to dig into the code to understand it.
Hmm, what are you thinking of when you say the HDF5 library uses
global, non-thread-specific data structures? (We try to eliminate those, and
if you can point us to something we've missed, we can probably fix it)
I can only speak to the first global I found to cause problems. There may be others. That was the
codestack:
In H5CS.c:
#ifdef H5_HAVE_THREADSAFE
/*
* The per-thread function stack. pthread_once() initializes a special
* key that will be used by all threads to create a stack specific to
* each thread individually. The association of stacks to threads will
* be handled by the pthread library.
*
* In order for this macro to work, H5CS_get_my_stack() must be preceeded
* by "H5CS_t *fstack =".
*/
static H5CS_t *H5CS_get_stack(void);
#define H5CS_get_my_stack() H5CS_get_stack()
#else /* H5_HAVE_THREADSAFE */
/*
* The function stack. Eventually we'll have some sort of global table so each
* thread has it's own stack. The stacks will be created on demand when the
* thread first calls H5CS_push(). */
H5CS_t H5CS_stack_g[1];
#define H5CS_get_my_stack() (H5CS_stack_g+0)
#endif /* H5_HAVE_THREADSAFE */
I see two solutions:
1. Fix codestack so it works for serialized, multithreaded programs even when HAVE_THREADSAFE is
undefined. This could be tricky since it'll need to deal with platforms that don't have threading at
all. I.e. it needs to test on HAVE_PTHREAD_H/HAVE_WIN_THREADS instead of HAVE_THREADSAFE. With no
platform threading at all the global variable is a reasonable solution.
2. Document or show a warning/error that codestack isn't safe to use in a multithreaded program even
if H5 calls are serialized.
I didn't think about it before but I could have just disabled codestack instead of giving up my goal
of serialized calls to the H5 API.
Thanks,
-Matt
_______________________________________________
Hdf-forum is for HDF software users discussion.
[email protected]
http://mail.hdfgroup.org/mailman/listinfo/hdf-forum_hdfgroup.org