int audit_log_buffer_write(audit_log_buffer_t *log, const char *buf, size_t len) { if (len > log->size) return(1); mysql_mutex_lock(&log->mutex); loop: if (log->write_pos + len < log->flush_pos + log->size) { size_t wrlen= min(len, log->size - (log->write_pos % log->size)); memcpy(log->buf + (log->write_pos % log->size), buf, wrlen); if (wrlen < len) memcpy(log->buf, buf + wrlen, len - wrlen); log->write_pos= log->write_pos + len; DBUG_ASSERT(log->write_pos >= log->flush_pos); } else { if (!log->drop_if_full) { mysql_cond_wait(&log->flushed_cond, &log->mutex); goto loop; } } if (log->write_pos > log->flush_pos + log->size / 2) { mysql_cond_signal(&log->written_cond); } mysql_mutex_unlock(&log->mutex); return(0); }
void test_concurrently(const char *test, pthread_handler handler, int n, int m) { pthread_t t; ulonglong now= my_getsystime(); bad= 0; diag("Testing %s with %d threads, %d iterations... ", test, n, m); for (running_threads= n ; n ; n--) { if (pthread_create(&t, &thr_attr, handler, &m) != 0) { diag("Could not create thread"); abort(); } } mysql_mutex_lock(&mutex); while (running_threads) mysql_cond_wait(&cond, &mutex); mysql_mutex_unlock(&mutex); now= my_getsystime()-now; ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e7, bad); }
/* 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; }