/* * __log_wrlsn_server -- * The log wrlsn server thread. */ static WT_THREAD_RET __log_wrlsn_server(void *arg) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; session = arg; conn = S2C(session); while (F_ISSET(conn, WT_CONN_LOG_SERVER_RUN)) { /* * Write out any log record buffers. */ WT_ERR(__wt_log_wrlsn(session)); WT_ERR(__wt_cond_wait(session, conn->log_wrlsn_cond, 10000)); } /* * On close we need to do this one more time because there could * be straggling log writes that need to be written. */ WT_ERR(__wt_log_force_write(session, 1)); WT_ERR(__wt_log_wrlsn(session)); if (0) { err: __wt_err(session, ret, "log wrlsn server error"); } return (WT_THREAD_RET_VALUE); }
/* * __log_slot_find_free -- * Find and return a free log slot. */ static int __log_slot_find_free(WT_SESSION_IMPL *session, WT_LOGSLOT **slot) { WT_CONNECTION_IMPL *conn; WT_LOG *log; uint32_t pool_i; conn = S2C(session); log = conn->log; WT_ASSERT(session, slot != NULL); /* * Encourage processing and moving the write LSN forward. * That process has to walk the slots anyway, so do that * work and let it give us the index of a free slot along * the way. */ WT_RET(__wt_log_wrlsn(session, &pool_i, NULL)); while (pool_i == WT_SLOT_POOL) { __wt_yield(); WT_RET(__wt_log_wrlsn(session, &pool_i, NULL)); } *slot = &log->slot_pool[pool_i]; WT_ASSERT(session, (*slot)->slot_state == WT_LOG_SLOT_FREE); return (0); }
/* * __log_wrlsn_server -- * The log wrlsn server thread. */ static WT_THREAD_RET __log_wrlsn_server(void *arg) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_LOG *log; WT_LSN prev; WT_SESSION_IMPL *session; int yield; bool did_work; session = arg; conn = S2C(session); log = conn->log; yield = 0; WT_INIT_LSN(&prev); did_work = false; while (F_ISSET(conn, WT_CONN_LOG_SERVER_RUN)) { /* * Write out any log record buffers if anything was done * since last time. Only call the function to walk the * slots if the system is not idle. On an idle system * the alloc_lsn will not advance and the written lsn will * match the alloc_lsn. */ if (__wt_log_cmp(&prev, &log->alloc_lsn) != 0 || __wt_log_cmp(&log->write_lsn, &log->alloc_lsn) != 0) WT_ERR(__wt_log_wrlsn(session, &yield)); else WT_STAT_FAST_CONN_INCR(session, log_write_lsn_skip); prev = log->alloc_lsn; if (yield == 0) did_work = true; else did_work = false; /* * If __wt_log_wrlsn did work we want to yield instead of sleep. */ if (yield++ < WT_THOUSAND) __wt_yield(); else /* * Send in false because if we did any work we would * not be on this path. */ WT_ERR(__wt_cond_auto_wait( session, conn->log_wrlsn_cond, did_work)); } /* * On close we need to do this one more time because there could * be straggling log writes that need to be written. */ WT_ERR(__wt_log_force_write(session, 1, NULL)); WT_ERR(__wt_log_wrlsn(session, NULL)); if (0) { err: __wt_err(session, ret, "log wrlsn server error"); } return (WT_THREAD_RET_VALUE); }
/* * __log_wrlsn_server -- * The log wrlsn server thread. */ static WT_THREAD_RET __log_wrlsn_server(void *arg) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_LOG *log; WT_SESSION_IMPL *session; int locked, yield; session = arg; conn = S2C(session); log = conn->log; locked = yield = 0; while (F_ISSET(conn, WT_CONN_LOG_SERVER_RUN)) { __wt_spin_lock(session, &log->log_slot_lock); locked = 1; WT_ERR(__wt_log_wrlsn(session, NULL, &yield)); locked = 0; __wt_spin_unlock(session, &log->log_slot_lock); if (++yield < 1000) __wt_yield(); else WT_ERR(__wt_cond_wait(session, conn->log_wrlsn_cond, 100000)); } if (0) { err: __wt_err(session, ret, "log wrlsn server error"); } if (locked) __wt_spin_unlock(session, &log->log_slot_lock); return (WT_THREAD_RET_VALUE); }