Bug #1187040: Random Segmentation faults on fileio test

Fixed a race condition in the test termination code with respect to
--report-interval: the reporting thread might read a non-zero
report_interval value and call print_stats(). If report_interval is
changed to 0 by the master thread and the test's done() method called,
print_stats() could access some shared resources deallocated in
done().

Fixed by protecting report_interval with a separate mutex which is
locked on updates and during the check by reporting thread and
print_stats().
This commit is contained in:
Alexey Kopytov
2013-06-11 18:55:57 +04:00
parent d52054be9e
commit df5e8f7e64

View File

@ -108,6 +108,8 @@ static double pareto_power; /* parameter pre-calculated by h */
static unsigned long long rnd_seed;
/* Mutex to protect random seed */
static pthread_mutex_t rnd_mutex;
/* Mutex to protect report_interval */
static pthread_mutex_t report_interval_mutex;
/* Stack size for each thread */
static int thread_stack_size;
@ -657,8 +659,11 @@ static void *report_thread_proc(void *arg)
sb_globals.report_interval may be set to 0 by the master thread
to silence report at the end of the test
*/
pthread_mutex_lock(&report_interval_mutex);
if (sb_globals.report_interval > 0)
current_test->ops.print_stats(SB_STAT_INTERMEDIATE);
pthread_mutex_unlock(&report_interval_mutex);
curr_ns = sb_timer_value(&sb_globals.exec_timer);
do
{
@ -785,6 +790,7 @@ static int run_test(sb_test_t *test)
/* Initialize random seed */
rnd_seed = LARGE_PRIME;
pthread_mutex_init(&rnd_mutex, NULL);
pthread_mutex_init(&report_interval_mutex, NULL);
if (sb_globals.report_interval > 0)
{
@ -859,7 +865,9 @@ static int run_test(sb_test_t *test)
sb_timer_stop(&sb_globals.cumulative_timer2);
/* Silence periodic reports if they were on */
pthread_mutex_lock(&report_interval_mutex);
sb_globals.report_interval = 0;
pthread_mutex_unlock(&report_interval_mutex);
#ifdef HAVE_ALARM
alarm(0);
@ -892,6 +900,8 @@ static int run_test(sb_test_t *test)
log_errno(LOG_FATAL, "Terminating the reporting thread failed.");
}
pthread_mutex_destroy(&report_interval_mutex);
if (eventgen_thread_created)
{
if (pthread_cancel(eventgen_thread) || pthread_join(eventgen_thread, NULL))