diff options
author | Michael Cahill <mjc@wiredtiger.com> | 2012-04-03 15:36:55 -0700 |
---|---|---|
committer | Michael Cahill <mjc@wiredtiger.com> | 2012-04-03 15:36:55 -0700 |
commit | 75bca7e8f18f1715e1e1d8b66b51533496ee5f4e (patch) | |
tree | d0082883bdbdd20af33d18178dd584aeada80922 | |
parent | 2da36349a2fb9884221806ff85abf934d032130c (diff) | |
parent | 7ef387690614ee39cc7fd735ccd0b88321f3f60d (diff) | |
download | mongo-75bca7e8f18f1715e1e1d8b66b51533496ee5f4e.tar.gz |
Merge pull request #188 from wiredtiger/feature/eviction-fixes
Merge eviction-fixes into develop.
-rw-r--r-- | src/btree/bt_discard.c | 2 | ||||
-rw-r--r-- | src/btree/bt_evict.c | 195 | ||||
-rw-r--r-- | src/btree/bt_walk.c | 10 | ||||
-rw-r--r-- | src/btree/rec_evict.c | 62 | ||||
-rw-r--r-- | src/include/btmem.h | 9 | ||||
-rw-r--r-- | src/include/extern.h | 1 |
6 files changed, 152 insertions, 127 deletions
diff --git a/src/btree/bt_discard.c b/src/btree/bt_discard.c index f77a89f3613..8ffb02ea271 100644 --- a/src/btree/bt_discard.c +++ b/src/btree/bt_discard.c @@ -32,6 +32,8 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) page->parent = NULL; page->ref = NULL; + WT_ASSERT(session, !F_ISSET(page, WT_PAGE_EVICT_LRU)); + /* If not a split merged into its parent, the page must be clean. */ WT_ASSERT(session, !__wt_page_is_modified(page) || diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c index c7a72bb5b45..86036d68553 100644 --- a/src/btree/bt_evict.c +++ b/src/btree/bt_evict.c @@ -7,12 +7,11 @@ #include "wt_internal.h" -static void __evict_dup_remove(WT_SESSION_IMPL *); static int __evict_file(WT_SESSION_IMPL *, WT_EVICT_REQ *); static int __evict_lru(WT_SESSION_IMPL *); static int __evict_lru_cmp(const void *, const void *); +static void __evict_lru_sort(WT_SESSION_IMPL *); static void __evict_pages(WT_SESSION_IMPL *); -static int __evict_page_cmp(const void *, const void *); static int __evict_request_walk(WT_SESSION_IMPL *); static int __evict_walk(WT_SESSION_IMPL *); static int __evict_walk_file(WT_SESSION_IMPL *, u_int *); @@ -40,13 +39,67 @@ static int __evict_worker(WT_SESSION_IMPL *); * Clear an entry in the eviction list. */ static inline void -__evict_clr(WT_EVICT_LIST *e) +__evict_clr(WT_SESSION_IMPL *session, WT_EVICT_LIST *e) { + if (e->page != NULL) { + WT_ASSERT(session, F_ISSET(e->page, WT_PAGE_EVICT_LRU)); + F_CLR(e->page, WT_PAGE_EVICT_LRU); + } e->page = NULL; e->btree = WT_DEBUG_POINT; } /* + * __evict_clr_all -- + * Clear all entries in the eviction list. + */ +static inline void +__evict_clr_all(WT_SESSION_IMPL *session) +{ + WT_CACHE *cache; + WT_EVICT_LIST *evict; + int i, elem; + + cache = S2C(session)->cache; + + elem = cache->evict_entries; + for (evict = cache->evict, i = 0; i < elem; i++, evict++) + __evict_clr(session, evict); +} + +/* + * __wt_evict_clr_page -- + * Make sure a page is not in the eviction request list. This called + * from inside __rec_review to make sure there is no attempt to evict + * child pages multiple times. + */ +void +__wt_evict_clr_page(WT_SESSION_IMPL *session, WT_PAGE *page) +{ + WT_CACHE *cache; + WT_EVICT_LIST *evict; + int i, elem; + + /* Fast path: if the page isn't on the queue, don't bother searching. */ + if (!F_ISSET(page, WT_PAGE_EVICT_LRU)) + return; + + cache = S2C(session)->cache; + __wt_spin_lock(session, &cache->lru_lock); + + elem = cache->evict_entries; + for (evict = cache->evict, i = 0; i < elem; i++, evict++) + if (evict->page == page) { + __evict_clr(session, evict); + break; + } + + WT_ASSERT(session, !F_ISSET(page, WT_PAGE_EVICT_LRU)); + + __wt_spin_unlock(session, &cache->lru_lock); +} + +/* * __evict_req_set -- * Set an entry in the eviction request list. */ @@ -353,7 +406,7 @@ __evict_request_walk(WT_SESSION_IMPL *session) * The eviction candidate list might reference pages we are * about to discard; clear it. */ - memset(cache->evict, 0, cache->evict_allocated); + __evict_clr_all(session); if (F_ISSET(er, WT_EVICT_REQ_PAGE)) { ref = er->page->ref; @@ -418,16 +471,20 @@ static int __evict_file(WT_SESSION_IMPL *session, WT_EVICT_REQ *er) { WT_PAGE *next_page, *page; + WT_REF *ref; WT_VERBOSE(session, evictserver, "file request: %s", (F_ISSET(er, WT_EVICT_REQ_CLOSE) ? "close" : "sync")); /* Clear the current eviction point. */ - if ((page = session->btree->evict_page) != NULL && - !WT_PAGE_IS_ROOT(page)) - (void)WT_ATOMIC_CAS(page->ref->state, - WT_REF_EVICT_WALK, WT_REF_MEM); + page = session->btree->evict_page; + while (page != NULL && !WT_PAGE_IS_ROOT(page)) { + ref = page->ref; + page = page->parent; + WT_ASSERT(session, ref->state == WT_REF_EVICT_WALK); + ref->state = WT_REF_MEM; + } session->btree->evict_page = NULL; /* If this is a close, wait for LRU eviction activity to drain. */ @@ -490,9 +547,9 @@ __evict_lru(WT_SESSION_IMPL *session) /* Get some more pages to consider for eviction. */ WT_RET(__evict_walk(session)); - /* Sort and remove duplicates from the list, restart. */ + /* Sort the list into LRU order and restart. */ __wt_spin_lock(session, &cache->lru_lock); - __evict_dup_remove(session); + __evict_lru_sort(session); cache->evict_current = cache->evict; __wt_spin_unlock(session, &cache->lru_lock); @@ -534,8 +591,8 @@ __evict_walk(WT_SESSION_IMPL *session) */ elem = WT_EVICT_WALK_BASE + (conn->btqcnt * WT_EVICT_WALK_PER_TABLE); if (elem > cache->evict_entries) { - __wt_spin_lock(session, &cache->lru_lock); /* Save the offset of the eviction point. */ + __wt_spin_lock(session, &cache->lru_lock); i = (u_int)(cache->evict_current - cache->evict); WT_ERR(__wt_realloc(session, &cache->evict_allocated, elem * sizeof(WT_EVICT_LIST), &cache->evict)); @@ -555,10 +612,13 @@ __evict_walk(WT_SESSION_IMPL *session) WT_CLEAR_BTREE_IN_SESSION(session); if (ret != 0) - goto err; + break; } -err: __wt_spin_unlock(session, &conn->spinlock); + if (0) { +err: __wt_spin_unlock(session, &cache->lru_lock); + } + __wt_spin_unlock(session, &conn->spinlock); return (ret); } @@ -571,11 +631,14 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp) { WT_BTREE *btree; WT_CACHE *cache; + WT_EVICT_LIST *end, *evict, *start; WT_PAGE *page; - int i, restarts, ret; + int restarts, ret; btree = session->btree; cache = S2C(session)->cache; + start = cache->evict + *slotp; + end = start + WT_EVICT_WALK_PER_TABLE; /* * Get the next WT_EVICT_WALK_PER_TABLE entries. @@ -583,8 +646,8 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp) * We can't evict the page just returned to us, it marks our place in * the tree. So, always stay one page ahead of the page being returned. */ - for (i = restarts = ret = 0; - i < WT_EVICT_WALK_PER_TABLE && restarts <= 1 && ret == 0; + for (evict = start, restarts = ret = 0; + evict < end && restarts <= 1 && ret == 0; ret = __wt_tree_np(session, &btree->evict_page, 1, 1)) { if ((page = btree->evict_page) == NULL) { ++restarts; @@ -593,40 +656,44 @@ __evict_walk_file(WT_SESSION_IMPL *session, u_int *slotp) /* * Root pages can't be evicted, nor can skip pages that must be - * merged into their parents. Don't skip pages marked - * WT_PAGE_REC_EMPTY or SPLIT: updates after their last - * reconciliation may have changed their state and only the - * eviction code can check whether they should really be - * skipped. + * merged into their parents. Use the EVICT_LRU flag to avoid + * putting pages onto the list multiple times. + * + * Don't skip pages marked WT_PAGE_REC_EMPTY or SPLIT: updates + * after their last reconciliation may have changed their state + * and only the eviction code can check whether they should + * really be skipped. */ if (WT_PAGE_IS_ROOT(page) || - F_ISSET(page, WT_PAGE_REC_SPLIT_MERGE)) + F_ISSET(page, WT_PAGE_EVICT_LRU | WT_PAGE_REC_SPLIT_MERGE)) continue; WT_VERBOSE(session, evictserver, "select: %p, size %" PRIu32, page, page->memory_footprint); - ++i; - cache->evict[*slotp].page = page; - cache->evict[*slotp].btree = btree; - ++*slotp; + WT_ASSERT(session, page->ref->state == WT_REF_EVICT_WALK); + + /* Mark the page on the list */ + F_SET(page, WT_PAGE_EVICT_LRU); + + __evict_clr(session, evict); + evict->page = page; + evict->btree = btree; + ++evict; } + *slotp += (u_int)(evict - start); return (ret); } /* - * __evict_dup_remove -- - * Discard duplicates from the list of pages we collected. + * __evict_lru_sort -- + * Sort the list of pages queued for eviction into LRU order. */ static void -__evict_dup_remove(WT_SESSION_IMPL *session) +__evict_lru_sort(WT_SESSION_IMPL *session) { WT_CACHE *cache; - WT_EVICT_LIST *evict; - u_int elem, i, j; - - cache = S2C(session)->cache; /* * We have an array of page eviction references that may contain NULLs, @@ -642,26 +709,9 @@ __evict_dup_remove(WT_SESSION_IMPL *session) * page and its parent, the duplicate of the page's WT_REF might have * been free'd before a subsequent review of the eviction array.) */ - evict = cache->evict; - elem = cache->evict_entries; - qsort(evict, elem, sizeof(WT_EVICT_LIST), __evict_page_cmp); - for (i = 0; i < elem; i = j) { - /* - * Once we hit a NULL, we're done, the NULLs all sorted to the - * end of the array. - */ - if (evict[i].page == NULL) - break; - - /* Delete any subsequent duplicates. */ - for (j = i + 1; - j < elem && evict[j].page == evict[i].page; - ++j) - __evict_clr(&evict[j]); - } - - /* Sort the array by LRU, then evict the most promising candidates. */ - qsort(evict, i, sizeof(WT_EVICT_LIST), __evict_lru_cmp); + cache = S2C(session)->cache; + qsort(cache->evict, + cache->evict_entries, sizeof(WT_EVICT_LIST), __evict_lru_cmp); } /* @@ -725,14 +775,14 @@ __evict_get_page( */ WT_ATOMIC_ADD(evict->btree->lru_count, 1); - *pagep = evict->page; *btreep = evict->btree; + *pagep = evict->page; /* - * Paranoia: remove the entry so we never try and reconcile - * the same page on reconciliation error. + * Remove the entry so we never try and reconcile the same page + * on reconciliation error. */ - __evict_clr(evict); + __evict_clr(session, evict); break; } @@ -789,35 +839,8 @@ __wt_evict_lru_page(WT_SESSION_IMPL *session, int is_app) static void __evict_pages(WT_SESSION_IMPL *session) { - u_int i; - - for (i = 0; i < WT_EVICT_GROUP / 2; i++) - if (__wt_evict_lru_page(session, 0) != 0) - break; -} - -/* - * __evict_page_cmp -- - * Qsort function: sort WT_EVICT_LIST array based on the page's address. - */ -static int -__evict_page_cmp(const void *a, const void *b) -{ - WT_PAGE *a_page, *b_page; - - /* - * There may be NULL references in the array; sort them as greater than - * anything else so they migrate to the end of the array. - */ - a_page = ((WT_EVICT_LIST *)a)->page; - b_page = ((WT_EVICT_LIST *)b)->page; - if (a_page == NULL) - return (b_page == NULL ? 0 : 1); - if (b_page == NULL) - return (-1); - - /* Sort the page address in ascending order. */ - return (a_page > b_page ? 1 : (a_page < b_page ? -1 : 0)); + while (__wt_evict_lru_page(session, 0) == 0) + ; } /* diff --git a/src/btree/bt_walk.c b/src/btree/bt_walk.c index 38aa8eb3eb8..990547ab947 100644 --- a/src/btree/bt_walk.c +++ b/src/btree/bt_walk.c @@ -62,11 +62,6 @@ __wt_tree_np(WT_SESSION_IMPL *session, WT_PAGE **pagep, int eviction, int next) * that can't be discarded. */ if (eviction) { - if (!WT_PAGE_IS_ROOT(t)) { - while (!WT_ATOMIC_CAS(t->ref->state, - WT_REF_MEM, WT_REF_EVICT_WALK)) - __wt_yield(); - } WT_ASSERT(session, page->ref->state == WT_REF_EVICT_WALK); page->ref->state = WT_REF_MEM; } else { @@ -107,11 +102,6 @@ descend: for (;;) { if (!WT_ATOMIC_CAS(ref->state, WT_REF_MEM, WT_REF_EVICT_WALK)) break; - if (!WT_PAGE_IS_ROOT(page)) { - WT_ASSERT(session, page->ref->state == - WT_REF_EVICT_WALK); - page->ref->state = WT_REF_MEM; - } } else { /* * Swap hazard references at each level (but diff --git a/src/btree/rec_evict.c b/src/btree/rec_evict.c index fa86b0a943f..b724739df48 100644 --- a/src/btree/rec_evict.c +++ b/src/btree/rec_evict.c @@ -8,15 +8,15 @@ #include "wt_internal.h" static int __hazard_exclusive(WT_SESSION_IMPL *, WT_REF *, int); -static int __rec_discard(WT_SESSION_IMPL *, WT_PAGE *); -static int __rec_discard_page(WT_SESSION_IMPL *, WT_PAGE *); +static int __rec_discard(WT_SESSION_IMPL *, WT_PAGE *, int); +static int __rec_discard_page(WT_SESSION_IMPL *, WT_PAGE *, int); static void __rec_excl_clear(WT_SESSION_IMPL *); -static int __rec_page_clean_update(WT_SESSION_IMPL *, WT_PAGE *); -static int __rec_page_dirty_update(WT_SESSION_IMPL *, WT_PAGE *); +static int __rec_page_clean_update(WT_SESSION_IMPL *, WT_PAGE *, int); +static int __rec_page_dirty_update(WT_SESSION_IMPL *, WT_PAGE *, int); static int __rec_review(WT_SESSION_IMPL *, WT_REF *, WT_PAGE *, uint32_t, int); static int __rec_root_addr_update(WT_SESSION_IMPL *, uint8_t *, uint32_t); -static int __rec_root_clean_update(WT_SESSION_IMPL *, WT_PAGE *); -static int __rec_root_dirty_update(WT_SESSION_IMPL *, WT_PAGE *); +static int __rec_root_clean_update(WT_SESSION_IMPL *, WT_PAGE *, int); +static int __rec_root_dirty_update(WT_SESSION_IMPL *, WT_PAGE *, int); /* * __wt_rec_evict -- @@ -26,7 +26,7 @@ int __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) { WT_CONNECTION_IMPL *conn; - int ret; + int ret, single; conn = S2C(session); ret = 0; @@ -35,6 +35,7 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) "page %p (%s)", page, __wt_page_type_string(page->type)); WT_ASSERT(session, session->excl_next == 0); + single = LF_ISSET(WT_REC_SINGLE) ? 1 : 0; /* * Get exclusive access to the page and review the page and its subtree @@ -51,7 +52,7 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) WT_ERR(__rec_review(session, page->ref, page, flags, 1)); /* Count evictions of internal pages during normal operation. */ - if (!LF_ISSET(WT_REC_SINGLE) && + if (!single && (page->type == WT_PAGE_COL_INT || page->type == WT_PAGE_ROW_INT)) WT_STAT_INCR(conn->stats, cache_evict_internal); @@ -60,16 +61,16 @@ __wt_rec_evict(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) WT_STAT_INCR(conn->stats, cache_evict_unmodified); if (WT_PAGE_IS_ROOT(page)) - WT_ERR(__rec_root_clean_update(session, page)); + WT_ERR(__rec_root_clean_update(session, page, single)); else - WT_ERR(__rec_page_clean_update(session, page)); + WT_ERR(__rec_page_clean_update(session, page, single)); } else { WT_STAT_INCR(conn->stats, cache_evict_modified); if (WT_PAGE_IS_ROOT(page)) - WT_ERR(__rec_root_dirty_update(session, page)); + WT_ERR(__rec_root_dirty_update(session, page, single)); else - WT_ERR(__rec_page_dirty_update(session, page)); + WT_ERR(__rec_page_dirty_update(session, page, single)); } if (0) { @@ -88,13 +89,13 @@ err: /* * Update a page's reference for an evicted, clean page. */ static int -__rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { /* Update the relevant WT_REF structure. */ WT_PUBLISH(page->ref->state, WT_REF_DISK); page->ref->page = NULL; - return (__rec_discard_page(session, page)); + return (__rec_discard_page(session, page, single)); } /* @@ -102,7 +103,7 @@ __rec_page_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page) * Update a page's reference for an evicted, clean page. */ static int -__rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { WT_BTREE *btree; @@ -110,7 +111,7 @@ __rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page) btree->root_page = NULL; - return (__rec_discard_page(session, page)); + return (__rec_discard_page(session, page, single)); } /* @@ -118,7 +119,7 @@ __rec_root_clean_update(WT_SESSION_IMPL *session, WT_PAGE *page) * Update a page's reference for an evicted, dirty page. */ static int -__rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { WT_PAGE_MODIFY *mod; WT_REF *parent_ref; @@ -170,7 +171,7 @@ __rec_page_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) * Discard pages which were merged into this page during reconciliation, * then discard the page itself. */ - WT_RET(__rec_discard(session, page)); + WT_RET(__rec_discard(session, page, single)); return (0); } @@ -206,7 +207,7 @@ __rec_root_addr_update(WT_SESSION_IMPL *session, uint8_t *addr, uint32_t size) * Update the reference for an evicted, dirty root page. */ static int -__rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { WT_BTREE *btree; WT_PAGE *next; @@ -248,7 +249,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) * Discard pages which were merged into this page during reconciliation, * then discard the page itself. */ - WT_RET(__rec_discard(session, page)); + WT_RET(__rec_discard(session, page, single)); if (next == NULL) return (0); @@ -274,7 +275,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) WT_RET(__wt_rec_write(session, next, NULL)); - return (__rec_root_dirty_update(session, next)); + return (__rec_root_dirty_update(session, next, single)); } /* @@ -282,7 +283,7 @@ __rec_root_dirty_update(WT_SESSION_IMPL *session, WT_PAGE *page) * Discard any pages merged into an evicted page, then the page itself. */ static int -__rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { WT_REF *ref; uint32_t i; @@ -291,12 +292,16 @@ __rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page) case WT_PAGE_COL_INT: case WT_PAGE_ROW_INT: /* For each entry in the page... */ - WT_REF_FOREACH(page, ref, i) - if (ref->state != WT_REF_DISK) - WT_RET(__rec_discard(session, ref->page)); + WT_REF_FOREACH(page, ref, i) { + if (ref->state == WT_REF_DISK) + continue; + WT_ASSERT(session, + single || ref->state == WT_REF_LOCKED); + WT_RET(__rec_discard(session, ref->page, single)); + } /* FALLTHROUGH */ default: - WT_RET(__rec_discard_page(session, page)); + WT_RET(__rec_discard_page(session, page, single)); break; } return (0); @@ -307,7 +312,7 @@ __rec_discard(WT_SESSION_IMPL *session, WT_PAGE *page) * Process the page's list of tracked objects, and discard it. */ static int -__rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page) +__rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page, int single) { WT_PAGE_MODIFY *mod; @@ -337,6 +342,9 @@ __rec_discard_page(WT_SESSION_IMPL *session, WT_PAGE *page) /* We should never evict the file's current eviction point. */ WT_ASSERT(session, session->btree->evict_page != page); + if (!single) + __wt_evict_clr_page(session, page); + /* Discard the page itself. */ __wt_page_out(session, page, 0); diff --git a/src/include/btmem.h b/src/include/btmem.h index e8ec2c7e9f7..b27cbeb3095 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -292,10 +292,11 @@ struct __wt_page { * the threads could race. */ #define WT_PAGE_BUILD_KEYS 0x001 /* Keys have been built in memory */ -#define WT_PAGE_REC_EMPTY 0x002 /* Reconciliation: page empty */ -#define WT_PAGE_REC_REPLACE 0x004 /* Reconciliation: page replaced */ -#define WT_PAGE_REC_SPLIT 0x008 /* Reconciliation: page split */ -#define WT_PAGE_REC_SPLIT_MERGE 0x010 /* Reconciliation: page split merge */ +#define WT_PAGE_EVICT_LRU 0x002 /* Page is on the LRU queue */ +#define WT_PAGE_REC_EMPTY 0x004 /* Reconciliation: page empty */ +#define WT_PAGE_REC_REPLACE 0x008 /* Reconciliation: page replaced */ +#define WT_PAGE_REC_SPLIT 0x010 /* Reconciliation: page split */ +#define WT_PAGE_REC_SPLIT_MERGE 0x020 /* Reconciliation: page split merge */ uint8_t flags; /* Page flags */ }; diff --git a/src/include/extern.h b/src/include/extern.h index e5d53b95ee3..652618bcd87 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -192,6 +192,7 @@ extern int __wt_debug_page(WT_SESSION_IMPL *session, extern void __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags); +extern void __wt_evict_clr_page(WT_SESSION_IMPL *session, WT_PAGE *page); extern void __wt_evict_server_wake(WT_SESSION_IMPL *session); extern void __wt_evict_file_serial_func(WT_SESSION_IMPL *session); extern int __wt_evict_page_request(WT_SESSION_IMPL *session, WT_PAGE *page); |