diff options
-rw-r--r-- | src/include/cache.i | 1 | ||||
-rw-r--r-- | src/log/log.c | 13 | ||||
-rw-r--r-- | src/log/log_slot.c | 8 | ||||
-rw-r--r-- | src/os_posix/os_mtx_rw.c | 18 |
4 files changed, 32 insertions, 8 deletions
diff --git a/src/include/cache.i b/src/include/cache.i index 0295451ef11..b1ace5e6a80 100644 --- a/src/include/cache.i +++ b/src/include/cache.i @@ -175,4 +175,3 @@ __wt_cache_full_check(WT_SESSION_IMPL *session) return (__wt_cache_wait(session, full)); } - diff --git a/src/log/log.c b/src/log/log.c index a173a829436..5e1256aec07 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -861,12 +861,12 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) WT_LOG *log; WT_LSN sync_lsn; size_t write_size; - int locked; + int locked, yield_count; WT_DECL_SPINLOCK_ID(id); /* Must appear last */ conn = S2C(session); log = conn->log; - locked = 0; + locked = yield_count = 0; /* Write the buffered records */ if (F_ISSET(slot, SLOT_BUFFERED)) { @@ -880,8 +880,13 @@ __log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) * Wait for earlier groups to finish, otherwise there could be holes * in the log file. */ - while (LOG_CMP(&log->write_lsn, &slot->slot_release_lsn) != 0) - __wt_yield(); + while (LOG_CMP(&log->write_lsn, &slot->slot_release_lsn) != 0) { + if (++yield_count < 100) + __wt_yield(); + else + WT_ERR(__wt_cond_wait( + session, log->log_write_cond, 2000)); + } log->write_lsn = slot->slot_end_lsn; WT_ERR(__wt_cond_signal(session, log->log_write_cond)); diff --git a/src/log/log_slot.c b/src/log/log_slot.c index cb959f28bd7..611587aaa8e 100644 --- a/src/log/log_slot.c +++ b/src/log/log_slot.c @@ -260,10 +260,16 @@ __wt_log_slot_notify(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) int __wt_log_slot_wait(WT_SESSION_IMPL *session, WT_LOGSLOT *slot) { + int yield_count; + + yield_count = 0; WT_UNUSED(session); while (slot->slot_state > WT_LOG_SLOT_DONE) - __wt_yield(); + if (++yield_count < 100) + __wt_yield(); + else + __wt_sleep(0, 2000); return (0); } diff --git a/src/os_posix/os_mtx_rw.c b/src/os_posix/os_mtx_rw.c index 4cda976bea8..b266d652671 100644 --- a/src/os_posix/os_mtx_rw.c +++ b/src/os_posix/os_mtx_rw.c @@ -95,6 +95,7 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) wt_rwlock_t *l; uint64_t me; uint16_t val; + int pause_cnt; WT_RET(__wt_verbose( session, WT_VERB_MUTEX, "rwlock: readlock %s", rwlock->name)); @@ -103,8 +104,21 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) l = &rwlock->rwlock; me = WT_ATOMIC_FETCH_ADD8(l->u, (uint64_t)1 << 32); val = (uint16_t)(me >> 32); - while (val != l->s.readers) - WT_PAUSE(); + for (pause_cnt = 0; val != l->s.readers;) { + /* + * We failed to get the lock; pause before retrying and if we've + * paused enough, sleep so we don't burn CPU to no purpose. This + * situation happens if there are more threads than cores in the + * system and we're thrashing on shared resources. Regardless, + * don't sleep long, all we need is to schedule the other reader + * threads to complete a few more instructions and increment the + * reader count. + */ + if (++pause_cnt < 1000) + WT_PAUSE(); + else + __wt_sleep(0, 10); + } ++l->s.readers; |