@@ -34,7 +34,8 @@ __wt_page_is_empty(WT_PAGE *page)
3434static inline bool
3535__wt_page_evict_clean (WT_PAGE *page)
3636{
37- return (page->modify == NULL || (page->modify ->write_gen == 0 &&
37+ return (page->modify == NULL ||
38+ (page->modify ->page_state == WT_PAGE_CLEAN &&
3839 page->modify ->rec_result == 0 ));
3940}
4041
@@ -45,7 +46,8 @@ __wt_page_evict_clean(WT_PAGE *page)
4546static inline bool
4647__wt_page_is_modified (WT_PAGE *page)
4748{
48- return (page->modify != NULL && page->modify ->write_gen != 0 );
49+ return (page->modify != NULL &&
50+ page->modify ->page_state != WT_PAGE_CLEAN);
4951}
5052
5153/*
@@ -496,19 +498,25 @@ __wt_page_only_modify_set(WT_SESSION_IMPL *session, WT_PAGE *page)
496498 WT_ASSERT (session, !F_ISSET (session->dhandle , WT_DHANDLE_DEAD));
497499
498500 last_running = 0 ;
499- if (page->modify ->write_gen == 0 )
501+ if (page->modify ->page_state == WT_PAGE_CLEAN )
500502 last_running = S2C (session)->txn_global .last_running ;
501503
502504 /*
503- * We depend on atomic-add being a write barrier, that is, a barrier to
504- * ensure all changes to the page are flushed before updating the page
505- * write generation and/or marking the tree dirty, otherwise checkpoints
505+ * We depend on the atomic operation being a write barrier, that is, a
506+ * barrier to ensure all changes to the page are flushed before updating
507+ * the page state and/or marking the tree dirty, otherwise checkpoints
506508 * and/or page reconciliation might be looking at a clean page/tree.
507509 *
508510 * Every time the page transitions from clean to dirty, update the cache
509511 * and transactional information.
512+ *
513+ * The page state can only ever be incremented above dirty by the number
514+ * of concurrently running threads, so the counter will never approach
515+ * the point where it would wrap.
510516 */
511- if (__wt_atomic_add32 (&page->modify ->write_gen , 1 ) == 1 ) {
517+ if (page->modify ->page_state < WT_PAGE_DIRTY &&
518+ __wt_atomic_add32 (&page->modify ->page_state , 1 ) ==
519+ WT_PAGE_DIRTY_FIRST) {
512520 __wt_cache_dirty_incr (session, page);
513521
514522 /*
@@ -579,7 +587,17 @@ __wt_page_modify_clear(WT_SESSION_IMPL *session, WT_PAGE *page)
579587 * Allow the call to be made on clean pages.
580588 */
581589 if (__wt_page_is_modified (page)) {
582- page->modify ->write_gen = 0 ;
590+ /*
591+ * The only part where ordering matters is during
592+ * reconciliation where updates on other threads are performing
593+ * writes to the page state that need to be visible to the
594+ * reconciliation thread.
595+ *
596+ * Since clearing of the page state is not going to be happening
597+ * during reconciliation on a separate thread, there's no write
598+ * barrier needed here.
599+ */
600+ page->modify ->page_state = WT_PAGE_CLEAN;
583601 __wt_cache_dirty_decr (session, page);
584602 }
585603}
0 commit comments