Trivial changes for thread sanitizer
Thread sanitizer warns about reads and writes of variables that are meant to be read without holding a lock: * Global "keep_going" is now a ddsrt_atomic_uint32_t * Thread "vtime" is now a ddsrt_atomic_uint32_t Previously the code relied on the assumption that a 32-bit int would be treated as atomic, now that is all wrapped in ddsrt_atomic_{ld,st}32. These being inline functions doing exactly the same thing, there is no functional change, but it does allow annotating the loads and stores for via function attributes on the ddsrt_atomic_{ld,st}X. The concurrent hashtable implementation is replaced by a locked version of the non-concurrent implementation if thread sanitizer is used. This changes eliminates the scores of problems signalled by thread sanitizer in the GUID-to-entity translation and the key-to-instance id lookups. Other than that, this replaces a flag used in a waitset test case to be a ddsrt_atomic_uint32_t. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
parent
0356af470d
commit
c6c5a872eb
17 changed files with 404 additions and 267 deletions
|
@ -20,6 +20,7 @@
|
|||
#include "dds/ddsrt/misc.h"
|
||||
#include "dds/ddsrt/process.h"
|
||||
#include "dds/ddsrt/threads.h"
|
||||
#include "dds/ddsrt/atomics.h"
|
||||
#include "dds/ddsrt/time.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
|
@ -36,7 +37,7 @@ typedef enum thread_state_t {
|
|||
|
||||
typedef struct thread_arg_t {
|
||||
ddsrt_thread_t tid;
|
||||
thread_state_t state;
|
||||
ddsrt_atomic_uint32_t state;
|
||||
dds_entity_t expected;
|
||||
} thread_arg_t;
|
||||
|
||||
|
@ -1056,26 +1057,26 @@ waiting_thread(void *a)
|
|||
dds_attach_t triggered;
|
||||
dds_return_t ret;
|
||||
|
||||
arg->state = WAITING;
|
||||
ddsrt_atomic_st32 (&arg->state, WAITING);
|
||||
/* This should block until the main test released all claims. */
|
||||
ret = dds_waitset_wait(waitset, &triggered, 1, DDS_SECS(1000));
|
||||
CU_ASSERT_EQUAL_FATAL(ret, 1);
|
||||
CU_ASSERT_EQUAL_FATAL(arg->expected, (dds_entity_t)(intptr_t)triggered);
|
||||
arg->state = STOPPED;
|
||||
ddsrt_atomic_st32 (&arg->state, STOPPED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static dds_return_t
|
||||
thread_reached_state(thread_state_t *actual, thread_state_t expected, int32_t msec)
|
||||
thread_reached_state(ddsrt_atomic_uint32_t *actual, thread_state_t expected, int32_t msec)
|
||||
{
|
||||
/* Convenience function. */
|
||||
dds_time_t msec10 = DDS_MSECS(10);
|
||||
while ((msec > 0) && (*actual != expected)) {
|
||||
while ((msec > 0) && ((thread_state_t) ddsrt_atomic_ld32 (actual) != expected)) {
|
||||
dds_sleepfor(msec10);
|
||||
msec -= 10;
|
||||
}
|
||||
return (*actual == expected) ? DDS_RETCODE_OK : DDS_RETCODE_TIMEOUT;
|
||||
return ((thread_state_t) ddsrt_atomic_ld32 (actual) == expected) ? DDS_RETCODE_OK : DDS_RETCODE_TIMEOUT;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1089,7 +1090,7 @@ waiting_thread_start(struct thread_arg_t *arg, dds_entity_t expected)
|
|||
|
||||
/* Create an other thread that will blocking wait on the waitset. */
|
||||
arg->expected = expected;
|
||||
arg->state = STARTING;
|
||||
ddsrt_atomic_st32 (&arg->state, STARTING);
|
||||
ddsrt_threadattr_init(&thread_attr);
|
||||
rc = ddsrt_thread_create(&thread_id, "waiting_thread", &thread_attr, waiting_thread, arg);
|
||||
CU_ASSERT_EQUAL_FATAL(rc, DDS_RETCODE_OK);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue