diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-10-16 17:49:50 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-10-16 17:49:50 +1100 |
commit | 044686f600158677da231fefac838d1fae857d93 (patch) | |
tree | 53a807890e39b363eec3e08fc8612664ebc49fd1 | |
parent | 44c514d20d27ffb6cc6770fe41e65267de63b17d (diff) | |
download | mongo-044686f600158677da231fefac838d1fae857d93.tar.gz |
Tweak the search loops in hazard_{set,clear} in favor of last-in-first-out ordering.
-rw-r--r-- | src/include/api.h | 5 | ||||
-rw-r--r-- | src/support/hazard.c | 24 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/include/api.h b/src/include/api.h index f5aa7bd9050..4dd3fa9392d 100644 --- a/src/include/api.h +++ b/src/include/api.h @@ -127,8 +127,9 @@ struct __wt_session_impl { * easily call a function to clear memory up to, but not including, the * hazard reference. */ - uint32_t hazard_size; /* Count of used hazard references */ - u_int nhazard; + uint32_t hazard_size; /* Allocated slots in hazard array. */ + uint32_t nhazard; /* Count of active hazard references */ + #define WT_SESSION_CLEAR(s) memset(s, 0, WT_PTRDIFF(&(s)->hazard, s)) WT_HAZARD *hazard; /* Hazard reference array */ }; diff --git a/src/support/hazard.c b/src/support/hazard.c index df362278d25..78dc1b5a1d8 100644 --- a/src/support/hazard.c +++ b/src/support/hazard.c @@ -24,6 +24,7 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, int *busyp { WT_BTREE *btree; WT_HAZARD *hp; + int restarts = 0; btree = session->btree; *busyp = 0; @@ -45,12 +46,23 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, int *busyp * reference before it discards the page (the eviction server sets the * state to WT_REF_LOCKED, then flushes memory and checks the hazard * references). + * + * For sessions with many active hazard references, skip most of the + * active slots: there may be a free slot in there, but checking is + * expensive. Most hazard references are released quickly: optimize + * for that case. */ - for (hp = session->hazard; ; ++hp) { + for (hp = session->hazard + session->nhazard;; ++hp) { /* Expand the number of hazard references if available.*/ if (hp >= session->hazard + session->hazard_size) { if (session->hazard_size >= S2C(session)->hazard_max) break; + /* Restart the search. */ + if (session->nhazard < session->hazard_size && + restarts++ == 0) { + hp = session->hazard; + continue; + } WT_PUBLISH(session->hazard_size, WT_MIN(session->hazard_size + WT_HAZARD_INCR, S2C(session)->hazard_max)); @@ -134,9 +146,13 @@ __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page) */ WT_ASSERT(session, page != NULL); - /* Clear the caller's hazard pointer. */ - for (hp = session->hazard; - hp < session->hazard + session->hazard_size; ++hp) + /* + * Clear the caller's hazard pointer. + * The common pattern is LIFO, so do a reverse search. + */ + for (hp = session->hazard + session->hazard_size - 1; + hp >= session->hazard; + --hp) if (hp->page == page) { /* * We don't publish the hazard reference clear in the |