@@ -34,7 +34,8 @@ __wt_page_is_empty(WT_PAGE *page)
34
34
static inline bool
35
35
__wt_page_evict_clean (WT_PAGE *page)
36
36
{
37
- return (page->modify == NULL || (page->modify ->write_gen == 0 &&
37
+ return (page->modify == NULL ||
38
+ (page->modify ->page_state == WT_PAGE_CLEAN &&
38
39
page->modify ->rec_result == 0 ));
39
40
}
40
41
@@ -45,7 +46,8 @@ __wt_page_evict_clean(WT_PAGE *page)
45
46
static inline bool
46
47
__wt_page_is_modified (WT_PAGE *page)
47
48
{
48
- return (page->modify != NULL && page->modify ->write_gen != 0 );
49
+ return (page->modify != NULL &&
50
+ page->modify ->page_state != WT_PAGE_CLEAN);
49
51
}
50
52
51
53
/*
@@ -496,19 +498,25 @@ __wt_page_only_modify_set(WT_SESSION_IMPL *session, WT_PAGE *page)
496
498
WT_ASSERT (session, !F_ISSET (session->dhandle , WT_DHANDLE_DEAD));
497
499
498
500
last_running = 0 ;
499
- if (page->modify ->write_gen == 0 )
501
+ if (page->modify ->page_state == WT_PAGE_CLEAN )
500
502
last_running = S2C (session)->txn_global .last_running ;
501
503
502
504
/*
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
506
508
* and/or page reconciliation might be looking at a clean page/tree.
507
509
*
508
510
* Every time the page transitions from clean to dirty, update the cache
509
511
* 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.
510
516
*/
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) {
512
520
__wt_cache_dirty_incr (session, page);
513
521
514
522
/*
@@ -579,7 +587,17 @@ __wt_page_modify_clear(WT_SESSION_IMPL *session, WT_PAGE *page)
579
587
* Allow the call to be made on clean pages.
580
588
*/
581
589
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;
583
601
__wt_cache_dirty_decr (session, page);
584
602
}
585
603
}
0 commit comments