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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy