Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 07e9e28

Browse files
committed
Add pg_memory_is_all_zeros() in memutils.h
This new function tests if a memory region starting at a given location for a defined length is made only of zeroes. This unifies in a single path the all-zero checks that were happening in a couple of places of the backend code: - For pgstats entries of relation, checkpointer and bgwriter, where some "all_zeroes" variables were previously used with memcpy(). - For all-zero buffer pages in PageIsVerifiedExtended(). This new function uses the same forward scan as the check for all-zero buffer pages, applying it to the three pgstats paths mentioned above. Author: Bertrand Drouvot Reviewed-by: Peter Eisentraut, Heikki Linnakangas, Peter Smith Discussion: https://postgr.es/m/ZupUDDyf1hHI4ibn@ip-10-97-1-34.eu-west-3.compute.internal
1 parent 49d6c7d commit 07e9e28

File tree

5 files changed

+26
-23
lines changed

5 files changed

+26
-23
lines changed

src/backend/storage/page/bufpage.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,8 @@ PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags)
8989
{
9090
PageHeader p = (PageHeader) page;
9191
size_t *pagebytes;
92-
int i;
9392
bool checksum_failure = false;
9493
bool header_sane = false;
95-
bool all_zeroes = false;
9694
uint16 checksum = 0;
9795

9896
/*
@@ -126,18 +124,9 @@ PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags)
126124
}
127125

128126
/* Check all-zeroes case */
129-
all_zeroes = true;
130127
pagebytes = (size_t *) page;
131-
for (i = 0; i < (BLCKSZ / sizeof(size_t)); i++)
132-
{
133-
if (pagebytes[i] != 0)
134-
{
135-
all_zeroes = false;
136-
break;
137-
}
138-
}
139128

140-
if (all_zeroes)
129+
if (pg_memory_is_all_zeros(pagebytes, (BLCKSZ / sizeof(size_t))))
141130
return true;
142131

143132
/*

src/backend/utils/activity/pgstat_bgwriter.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "postgres.h"
1919

20+
#include "utils/memutils.h"
2021
#include "utils/pgstat_internal.h"
2122

2223

@@ -30,7 +31,6 @@ void
3031
pgstat_report_bgwriter(void)
3132
{
3233
PgStatShared_BgWriter *stats_shmem = &pgStatLocal.shmem->bgwriter;
33-
static const PgStat_BgWriterStats all_zeroes;
3434

3535
Assert(!pgStatLocal.shmem->is_shutdown);
3636
pgstat_assert_is_up();
@@ -39,7 +39,8 @@ pgstat_report_bgwriter(void)
3939
* This function can be called even if nothing at all has happened. In
4040
* this case, avoid unnecessarily modifying the stats entry.
4141
*/
42-
if (memcmp(&PendingBgWriterStats, &all_zeroes, sizeof(all_zeroes)) == 0)
42+
if (pg_memory_is_all_zeros(&PendingBgWriterStats,
43+
sizeof(struct PgStat_BgWriterStats)))
4344
return;
4445

4546
pgstat_begin_changecount_write(&stats_shmem->changecount);

src/backend/utils/activity/pgstat_checkpointer.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "postgres.h"
1919

20+
#include "utils/memutils.h"
2021
#include "utils/pgstat_internal.h"
2122

2223

@@ -29,8 +30,6 @@ PgStat_CheckpointerStats PendingCheckpointerStats = {0};
2930
void
3031
pgstat_report_checkpointer(void)
3132
{
32-
/* We assume this initializes to zeroes */
33-
static const PgStat_CheckpointerStats all_zeroes;
3433
PgStatShared_Checkpointer *stats_shmem = &pgStatLocal.shmem->checkpointer;
3534

3635
Assert(!pgStatLocal.shmem->is_shutdown);
@@ -40,8 +39,8 @@ pgstat_report_checkpointer(void)
4039
* This function can be called even if nothing at all has happened. In
4140
* this case, avoid unnecessarily modifying the stats entry.
4241
*/
43-
if (memcmp(&PendingCheckpointerStats, &all_zeroes,
44-
sizeof(all_zeroes)) == 0)
42+
if (pg_memory_is_all_zeros(&PendingCheckpointerStats,
43+
sizeof(struct PgStat_CheckpointerStats)))
4544
return;
4645

4746
pgstat_begin_changecount_write(&stats_shmem->changecount);

src/backend/utils/activity/pgstat_relation.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,6 @@ pgstat_twophase_postabort(TransactionId xid, uint16 info,
800800
bool
801801
pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
802802
{
803-
static const PgStat_TableCounts all_zeroes;
804803
Oid dboid;
805804
PgStat_TableStatus *lstats; /* pending stats entry */
806805
PgStatShared_Relation *shtabstats;
@@ -815,11 +814,9 @@ pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
815814
* Ignore entries that didn't accumulate any actual counts, such as
816815
* indexes that were opened by the planner but not used.
817816
*/
818-
if (memcmp(&lstats->counts, &all_zeroes,
819-
sizeof(PgStat_TableCounts)) == 0)
820-
{
817+
if (pg_memory_is_all_zeros(&lstats->counts,
818+
sizeof(struct PgStat_TableCounts)))
821819
return true;
822-
}
823820

824821
if (!pgstat_lock_entry(entry_ref, nowait))
825822
return false;

src/include/utils/memutils.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,21 @@ extern MemoryContext BumpContextCreate(MemoryContext parent,
189189
#define SLAB_DEFAULT_BLOCK_SIZE (8 * 1024)
190190
#define SLAB_LARGE_BLOCK_SIZE (8 * 1024 * 1024)
191191

192+
/*
193+
* Test if a memory region starting at "ptr" and of size "len" is full of
194+
* zeroes.
195+
*/
196+
static inline bool
197+
pg_memory_is_all_zeros(const void *ptr, size_t len)
198+
{
199+
const char *p = (const char *) ptr;
200+
201+
for (size_t i = 0; i < len; i++)
202+
{
203+
if (p[i] != 0)
204+
return false;
205+
}
206+
return true;
207+
}
208+
192209
#endif /* MEMUTILS_H */

0 commit comments

Comments
 (0)