添加内存屏障,保证读取的变量是当前最新值

This commit is contained in:
LiHeng 2021-08-04 16:52:58 +08:00 committed by cchen676
parent a7e92ffd28
commit 561ba0ebcd
4 changed files with 15 additions and 8 deletions

View File

@ -1117,7 +1117,9 @@ static void candidate_buf_push(int buf_id, int thread_id)
uint32 list_size = bgwriter->cand_list_size;
uint32 tail_loc;
pg_memory_barrier();
volatile uint64 head = pg_atomic_read_u64(&bgwriter->head);
pg_memory_barrier();
volatile uint64 tail = pg_atomic_read_u64(&bgwriter->tail);
if (unlikely(tail - head >= list_size)) {
@ -1126,8 +1128,8 @@ static void candidate_buf_push(int buf_id, int thread_id)
}
tail_loc = tail % list_size;
bgwriter->cand_buf_list[tail_loc] = buf_id;
pg_write_barrier();
(void)pg_atomic_fetch_add_u64(&bgwriter->tail, 1);
pg_memory_barrier();
}
/**
@ -1142,17 +1144,19 @@ bool candidate_buf_pop(int *buf_id, int thread_id)
uint32 head_loc;
while (true) {
pg_memory_barrier();
uint64 head = pg_atomic_read_u64(&bgwriter->head);
pg_memory_barrier();
volatile uint64 tail = pg_atomic_read_u64(&bgwriter->tail);
if (unlikely(head >= tail)) {
return false; /* candidate list is empty */
}
pg_write_barrier();
head_loc = head % list_size;
*buf_id = bgwriter->cand_buf_list[head_loc];
if (pg_atomic_compare_exchange_u64(&bgwriter->head, &head, head + 1)) {
pg_memory_barrier();
return true;
}
}
@ -1162,6 +1166,7 @@ static int64 get_thread_candidate_nums(int thread_id)
{
BgWriterProc *bgwriter = &g_instance.bgwriter_cxt.bgwriter_procs[thread_id];
volatile uint64 head = pg_atomic_read_u64(&bgwriter->head);
pg_memory_barrier();
volatile uint64 tail = pg_atomic_read_u64(&bgwriter->tail);
int64 curr_cand_num = tail - head;
Assert(curr_cand_num >= 0);

View File

@ -338,7 +338,7 @@ bool push_pending_flush_queue(Buffer buffer)
actual_loc = new_tail_loc % g_instance.ckpt_cxt_ctl->dirty_page_queue_size;
buf_desc->dirty_queue_loc = actual_loc;
g_instance.ckpt_cxt_ctl->dirty_page_queue[actual_loc].buffer = buffer;
pg_write_barrier();
pg_memory_barrier();
pg_atomic_write_u32(&g_instance.ckpt_cxt_ctl->dirty_page_queue[actual_loc].slot_state, (SLOT_VALID));
(void)pg_atomic_fetch_add_u32(&g_instance.ckpt_cxt_ctl->actual_dirty_page_num, 1);
return true;
@ -463,7 +463,7 @@ try_get_buf:
if (!(pg_atomic_read_u32(&slot->slot_state) & SLOT_VALID)) {
break;
}
pg_read_barrier();
pg_memory_barrier();
buffer = slot->buffer;
/* slot state is valid, buffer is invalid, the slot buffer set 0 when BufferAlloc or InvalidateBuffer */
if (BufferIsInvalid(buffer)) {
@ -1344,6 +1344,7 @@ static void ckpt_try_prune_dirty_page_queue()
* the redo point will be wrong, because some page not flush to disk.
*/
(void)LWLockAcquire(g_instance.ckpt_cxt_ctl->prune_queue_lock, LW_EXCLUSIVE);
pg_memory_barrier();
if (last_invalid_slot > pg_atomic_read_u64(&g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc)) {
pg_atomic_write_u64(&g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc, (last_invalid_slot + 1));
}

View File

@ -10936,7 +10936,7 @@ void CreateCheckPoint(int flags)
*/
g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc = get_dirty_page_queue_tail();
g_instance.ckpt_cxt_ctl->full_ckpt_redo_ptr = curInsert;
pg_write_barrier();
pg_memory_barrier();
if (get_dirty_page_num() > 0) {
g_instance.ckpt_cxt_ctl->flush_all_dirty_page = true;
}
@ -11537,7 +11537,7 @@ void wait_all_dirty_page_flush(int flags, XLogRecPtr redo)
if (ENABLE_INCRE_CKPT) {
g_instance.ckpt_cxt_ctl->full_ckpt_redo_ptr = redo;
g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc = get_dirty_page_queue_tail();
pg_write_barrier();
pg_memory_barrier();
if (get_dirty_page_num() > 0) {
g_instance.ckpt_cxt_ctl->flush_all_dirty_page = true;
ereport(LOG, (errmsg("CreateRestartPoint, need flush %ld pages.", get_dirty_page_num())));
@ -11806,7 +11806,7 @@ bool CreateRestartPoint(int flags)
if (ENABLE_INCRE_CKPT && doFullCkpt) {
g_instance.ckpt_cxt_ctl->full_ckpt_redo_ptr = lastCheckPoint.redo;
g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc = get_dirty_page_queue_tail();
pg_write_barrier();
pg_memory_barrier();
if (get_dirty_page_num() > 0) {
g_instance.ckpt_cxt_ctl->flush_all_dirty_page = true;
}
@ -11815,8 +11815,8 @@ bool CreateRestartPoint(int flags)
g_instance.ckpt_cxt_ctl->full_ckpt_redo_ptr = lastCheckPoint.redo;
(void)LWLockAcquire(g_instance.ckpt_cxt_ctl->prune_queue_lock, LW_EXCLUSIVE);
g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc = get_loc_for_lsn(lastCheckPointRecPtr);
pg_memory_barrier();
LWLockRelease(g_instance.ckpt_cxt_ctl->prune_queue_lock);
pg_write_barrier();
uint64 head = pg_atomic_read_u64(&g_instance.ckpt_cxt_ctl->dirty_page_queue_head);
int64 need_flush_num = g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc > head ?

View File

@ -3890,6 +3890,7 @@ void CheckPointBuffers(int flags, bool doFullCheckpoint)
* dirty page num.
*/
for (;;) {
pg_memory_barrier();
if ((pg_atomic_read_u64(&g_instance.ckpt_cxt_ctl->dirty_page_queue_head) >=
pg_atomic_read_u64(&g_instance.ckpt_cxt_ctl->full_ckpt_expected_flush_loc)) ||
get_dirty_page_num() == 0) {