static void audit_log_flush(audit_log_buffer_t *log) { mysql_mutex_lock(&log->mutex); while (log->flush_pos == log->write_pos) { struct timespec abstime; if (log->stop) { mysql_mutex_unlock(&log->mutex); return; } set_timespec(abstime, 1); mysql_cond_timedwait(&log->written_cond, &log->mutex, &abstime); } if (log->flush_pos > log->write_pos % log->size) { mysql_mutex_unlock(&log->mutex); log->write_func(log->write_func_data, log->buf + log->flush_pos, log->size - log->flush_pos, LOG_RECORD_INCOMPLETE); mysql_mutex_lock(&log->mutex); log->flush_pos= 0; log->write_pos%= log->size; } else { size_t flushlen= log->write_pos - log->flush_pos; mysql_mutex_unlock(&log->mutex); log->write_func(log->write_func_data, log->buf + log->flush_pos, flushlen, LOG_RECORD_COMPLETE); mysql_mutex_lock(&log->mutex); log->flush_pos+= flushlen; } DBUG_ASSERT(log->write_pos >= log->flush_pos); mysql_cond_broadcast(&log->flushed_cond); mysql_mutex_unlock(&log->mutex); }
/* stress test: wait on a random number of random threads. it always succeeds (unless crashes or hangs). */ pthread_handler_t test_wt(void *arg) { int m, n, i, id, res; struct my_rnd_struct rand; my_thread_init(); mysql_mutex_lock(&mutex); id= cnt++; wt_thd_lazy_init(& thds[id].thd, & wt_deadlock_search_depth_short, & wt_timeout_short, & wt_deadlock_search_depth_long, & wt_timeout_long); /* now, wait for everybody to be ready to run */ if (cnt >= THREADS) mysql_cond_broadcast(&thread_sync); else while (cnt < THREADS) mysql_cond_wait(&thread_sync, &mutex); mysql_mutex_unlock(&mutex); my_rnd_init(&rand, (ulong)(intptr)&m, id); if (kill_strategy == YOUNGEST) thds[id].thd.weight= (ulong)~my_getsystime(); if (kill_strategy == LOCKS) thds[id].thd.weight= 0; for (m= *(int *)arg; m ; m--) { WT_RESOURCE_ID resid; int blockers[THREADS/10], j, k; resid.value= id; resid.type= &restype; res= 0; /* prepare for waiting for a random number of random threads */ for (j= n= (rnd() % THREADS)/10; !res && j >= 0; j--) { retry: i= rnd() % (THREADS-1); /* pick a random thread */ if (i >= id) i++; /* with a number from 0 to THREADS-1 excluding ours */ for (k=n; k >=j; k--) /* the one we didn't pick before */ if (blockers[k] == i) goto retry; blockers[j]= i; if (kill_strategy == RANDOM) thds[id].thd.weight= rnd(); mysql_mutex_lock(& thds[i].lock); res= wt_thd_will_wait_for(& thds[id].thd, & thds[i].thd, &resid); mysql_mutex_unlock(& thds[i].lock); } if (!res) { mysql_mutex_lock(&lock); res= wt_thd_cond_timedwait(& thds[id].thd, &lock); mysql_mutex_unlock(&lock); } if (res) { mysql_mutex_lock(& thds[id].lock); mysql_mutex_lock(&lock); wt_thd_release_all(& thds[id].thd); mysql_mutex_unlock(&lock); mysql_mutex_unlock(& thds[id].lock); if (kill_strategy == LOCKS) thds[id].thd.weight= 0; if (kill_strategy == YOUNGEST) thds[id].thd.weight= (ulong)~my_getsystime(); } else if (kill_strategy == LOCKS) thds[id].thd.weight++; } mysql_mutex_lock(&mutex); /* wait for everybody to finish */ if (!--cnt) mysql_cond_broadcast(&thread_sync); else while (cnt) mysql_cond_wait(&thread_sync, &mutex); mysql_mutex_lock(& thds[id].lock); mysql_mutex_lock(&lock); wt_thd_release_all(& thds[id].thd); mysql_mutex_unlock(&lock); mysql_mutex_unlock(& thds[id].lock); wt_thd_destroy(& thds[id].thd); if (!--running_threads) /* now, signal when everybody is done with deinit */ mysql_cond_signal(&cond); mysql_mutex_unlock(&mutex); DBUG_PRINT("wt", ("exiting")); my_thread_end(); return 0; }