summaryrefslogtreecommitdiff
path: root/src/log/log_slot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/log/log_slot.c')
-rw-r--r--src/log/log_slot.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/src/log/log_slot.c b/src/log/log_slot.c
index 97e317ce68c..5bd3d53a973 100644
--- a/src/log/log_slot.c
+++ b/src/log/log_slot.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014-2016 MongoDB, Inc.
+ * Copyright (c) 2014-2017 MongoDB, Inc.
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
@@ -126,13 +126,17 @@ retry:
* processed by another closing thread. Only return 0 when we
* actually closed the slot.
*/
- if (WT_LOG_SLOT_CLOSED(old_state))
+ if (WT_LOG_SLOT_CLOSED(old_state)) {
+ WT_STAT_CONN_INCR(session, log_slot_close_race);
return (WT_NOTFOUND);
+ }
/*
* If someone completely processed this slot, we're done.
*/
- if (FLD64_ISSET((uint64_t)slot->slot_state, WT_LOG_SLOT_RESERVED))
+ if (FLD64_ISSET((uint64_t)slot->slot_state, WT_LOG_SLOT_RESERVED)) {
+ WT_STAT_CONN_INCR(session, log_slot_close_race);
return (WT_NOTFOUND);
+ }
new_state = (old_state | WT_LOG_SLOT_CLOSE);
/*
* Close this slot. If we lose the race retry.
@@ -160,7 +164,7 @@ retry:
#endif
if (WT_LOG_SLOT_UNBUFFERED_ISSET(old_state)) {
while (slot->slot_unbuffered == 0) {
- WT_RET(WT_SESSION_CHECK_PANIC(session));
+ WT_STAT_CONN_INCR(session, log_slot_close_unbuf);
__wt_yield();
#ifdef HAVE_DIAGNOSTIC
++count;
@@ -250,8 +254,6 @@ __log_slot_new(WT_SESSION_IMPL *session)
* We have a new, initialized slot to use.
* Set it as the active slot.
*/
- WT_STAT_CONN_INCR(session,
- log_slot_transitions);
log->active_slot = slot;
log->pool_index = pool_i;
return (0);
@@ -318,7 +320,6 @@ __log_slot_switch_internal(
*did_work = false;
return (0);
}
- WT_RET(WT_SESSION_CHECK_PANIC(session));
/*
* We may come through here multiple times if we were not able to
@@ -401,7 +402,7 @@ __wt_log_slot_switch(WT_SESSION_IMPL *session,
* Initialize the slot array.
*/
int
-__wt_log_slot_init(WT_SESSION_IMPL *session)
+__wt_log_slot_init(WT_SESSION_IMPL *session, bool alloc)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
@@ -423,15 +424,17 @@ __wt_log_slot_init(WT_SESSION_IMPL *session)
* switch log files very aggressively. Scale back the buffer for
* small log file sizes.
*/
- log->slot_buf_size = (uint32_t)WT_MIN(
- (size_t)conn->log_file_max / 10, WT_LOG_SLOT_BUF_SIZE);
- for (i = 0; i < WT_SLOT_POOL; i++) {
- WT_ERR(__wt_buf_init(session,
- &log->slot_pool[i].slot_buf, log->slot_buf_size));
- F_SET(&log->slot_pool[i], WT_SLOT_INIT_FLAGS);
+ if (alloc) {
+ log->slot_buf_size = (uint32_t)WT_MIN(
+ (size_t)conn->log_file_max / 10, WT_LOG_SLOT_BUF_SIZE);
+ for (i = 0; i < WT_SLOT_POOL; i++) {
+ WT_ERR(__wt_buf_init(session,
+ &log->slot_pool[i].slot_buf, log->slot_buf_size));
+ F_SET(&log->slot_pool[i], WT_SLOT_INIT_FLAGS);
+ }
+ WT_STAT_CONN_SET(session,
+ log_buffer_size, log->slot_buf_size * WT_SLOT_POOL);
}
- WT_STAT_CONN_SET(session,
- log_buffer_size, log->slot_buf_size * WT_SLOT_POOL);
/*
* Set up the available slot from the pool the first time.
*/
@@ -492,16 +495,18 @@ __wt_log_slot_destroy(WT_SESSION_IMPL *session)
* __wt_log_slot_join --
* Join a consolidated logging slot.
*/
-int
+void
__wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
uint32_t flags, WT_MYSLOT *myslot)
{
+ struct timespec start, stop;
WT_CONNECTION_IMPL *conn;
WT_LOG *log;
WT_LOGSLOT *slot;
+ uint64_t usecs;
int64_t flag_state, new_state, old_state, released;
- int32_t join_offset, new_join;
- bool unbuffered, yld;
+ int32_t join_offset, new_join, wait_cnt;
+ bool closed, diag_yield, raced, slept, unbuffered, yielded;
conn = S2C(session);
log = conn->log;
@@ -512,13 +517,15 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
/*
* There should almost always be a slot open.
*/
- unbuffered = false;
+ unbuffered = yielded = false;
+ closed = raced = slept = false;
+ wait_cnt = 0;
#ifdef HAVE_DIAGNOSTIC
- yld = (++log->write_calls % 7) == 0;
+ diag_yield = (++log->write_calls % 7) == 0;
if ((log->write_calls % WT_THOUSAND) == 0 ||
mysize > WT_LOG_SLOT_BUF_MAX) {
#else
- yld = false;
+ diag_yield = false;
if (mysize > WT_LOG_SLOT_BUF_MAX) {
#endif
unbuffered = true;
@@ -526,7 +533,6 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
}
for (;;) {
WT_BARRIER();
- WT_RET(WT_SESSION_CHECK_PANIC(session));
slot = log->active_slot;
old_state = slot->slot_state;
if (WT_LOG_SLOT_OPEN(old_state)) {
@@ -548,7 +554,7 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
/*
* Braces used due to potential empty body warning.
*/
- if (yld) {
+ if (diag_yield) {
WT_DIAGNOSTIC_YIELD;
}
/*
@@ -558,19 +564,44 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
&slot->slot_state, old_state, new_state))
break;
WT_STAT_CONN_INCR(session, log_slot_races);
- } else
+ raced = true;
+ } else {
WT_STAT_CONN_INCR(session, log_slot_active_closed);
+ closed = true;
+ ++wait_cnt;
+ }
+ if (!yielded)
+ __wt_epoch(session, &start);
+ yielded = true;
/*
* The slot is no longer open or we lost the race to
* update it. Yield and try again.
*/
- __wt_yield();
+ if (wait_cnt < WT_THOUSAND)
+ __wt_yield();
+ else {
+ __wt_sleep(0, WT_THOUSAND);
+ slept = true;
+ }
}
/*
* We joined this slot. Fill in our information to return to
* the caller.
*/
- WT_STAT_CONN_INCR(session, log_slot_joins);
+ if (!yielded)
+ WT_STAT_CONN_INCR(session, log_slot_immediate);
+ else {
+ WT_STAT_CONN_INCR(session, log_slot_yield);
+ __wt_epoch(session, &stop);
+ usecs = WT_TIMEDIFF_US(stop, start);
+ WT_STAT_CONN_INCRV(session, log_slot_yield_duration, usecs);
+ if (closed)
+ WT_STAT_CONN_INCR(session, log_slot_yield_close);
+ if (raced)
+ WT_STAT_CONN_INCR(session, log_slot_yield_race);
+ if (slept)
+ WT_STAT_CONN_INCR(session, log_slot_yield_sleep);
+ }
if (LF_ISSET(WT_LOG_DSYNC | WT_LOG_FSYNC))
F_SET(slot, WT_SLOT_SYNC_DIR);
if (LF_ISSET(WT_LOG_FLUSH))
@@ -585,7 +616,6 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
myslot->slot = slot;
myslot->offset = join_offset;
myslot->end_offset = (wt_off_t)((uint64_t)join_offset + mysize);
- return (0);
}
/*
@@ -595,7 +625,7 @@ __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize,
* the memory buffer.
*/
int64_t
-__wt_log_slot_release(WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int64_t size)
+__wt_log_slot_release(WT_MYSLOT *myslot, int64_t size)
{
WT_LOGSLOT *slot;
wt_off_t cur_offset, my_start;
@@ -609,7 +639,6 @@ __wt_log_slot_release(WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int64_t size)
* was written rather than the beginning record of the slot.
*/
while ((cur_offset = slot->slot_last_offset) < my_start) {
- WT_RET(WT_SESSION_CHECK_PANIC(session));
/*
* Set our offset if we are larger.
*/