Skip to content

Commit 8c8a886

Browse files
committed
Add palloc_extended for frontend and backend.
This commit also adds pg_malloc_extended for frontend. These interfaces can be used to control at a lower level memory allocation using an interface similar to MemoryContextAllocExtended. For example, the callers can specify MCXT_ALLOC_NO_OOM if they want to suppress the "out of memory" error while allocating the memory and handle a NULL return value. Michael Paquier, reviewed by me.
1 parent bc49d93 commit 8c8a886

File tree

4 files changed

+85
-12
lines changed

4 files changed

+85
-12
lines changed

src/backend/utils/mmgr/mcxt.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,43 @@ palloc0(Size size)
864864
return ret;
865865
}
866866

867+
void *
868+
palloc_extended(Size size, int flags)
869+
{
870+
/* duplicates MemoryContextAllocExtended to avoid increased overhead */
871+
void *ret;
872+
873+
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
874+
AssertNotInCriticalSection(CurrentMemoryContext);
875+
876+
if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
877+
((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
878+
elog(ERROR, "invalid memory alloc request size %zu", size);
879+
880+
CurrentMemoryContext->isReset = false;
881+
882+
ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
883+
if (ret == NULL)
884+
{
885+
if ((flags & MCXT_ALLOC_NO_OOM) == 0)
886+
{
887+
MemoryContextStats(TopMemoryContext);
888+
ereport(ERROR,
889+
(errcode(ERRCODE_OUT_OF_MEMORY),
890+
errmsg("out of memory"),
891+
errdetail("Failed on request of size %zu.", size)));
892+
}
893+
return NULL;
894+
}
895+
896+
VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size);
897+
898+
if ((flags & MCXT_ALLOC_ZERO) != 0)
899+
MemSetAligned(ret, 0, size);
900+
901+
return ret;
902+
}
903+
867904
/*
868905
* pfree
869906
* Release an allocated chunk.

src/common/fe_memutils.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,46 @@
1919

2020
#include "postgres_fe.h"
2121

22-
void *
23-
pg_malloc(size_t size)
22+
static inline void *
23+
pg_malloc_internal(size_t size, int flags)
2424
{
2525
void *tmp;
2626

2727
/* Avoid unportable behavior of malloc(0) */
2828
if (size == 0)
2929
size = 1;
3030
tmp = malloc(size);
31-
if (!tmp)
31+
if (tmp == NULL)
3232
{
33-
fprintf(stderr, _("out of memory\n"));
34-
exit(EXIT_FAILURE);
33+
if ((flags & MCXT_ALLOC_NO_OOM) == 0)
34+
{
35+
fprintf(stderr, _("out of memory\n"));
36+
exit(EXIT_FAILURE);
37+
}
38+
return NULL;
3539
}
40+
41+
if ((flags & MCXT_ALLOC_ZERO) != 0)
42+
MemSet(tmp, 0, size);
3643
return tmp;
3744
}
3845

46+
void *
47+
pg_malloc(size_t size)
48+
{
49+
return pg_malloc_internal(size, 0);
50+
}
51+
3952
void *
4053
pg_malloc0(size_t size)
4154
{
42-
void *tmp;
55+
return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
56+
}
4357

44-
tmp = pg_malloc(size);
45-
MemSet(tmp, 0, size);
46-
return tmp;
58+
void *
59+
pg_malloc_extended(size_t size, int flags)
60+
{
61+
return pg_malloc_internal(size, flags);
4762
}
4863

4964
void *
@@ -100,13 +115,19 @@ pg_free(void *ptr)
100115
void *
101116
palloc(Size size)
102117
{
103-
return pg_malloc(size);
118+
return pg_malloc_internal(size, 0);
104119
}
105120

106121
void *
107122
palloc0(Size size)
108123
{
109-
return pg_malloc0(size);
124+
return pg_malloc_internal(size, MCXT_ALLOC_ZERO);
125+
}
126+
127+
void *
128+
palloc_extended(Size size, int flags)
129+
{
130+
return pg_malloc_internal(size, flags);
110131
}
111132

112133
void

src/include/common/fe_memutils.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,31 @@
99
#ifndef FE_MEMUTILS_H
1010
#define FE_MEMUTILS_H
1111

12-
/* "Safe" memory allocation functions --- these exit(1) on failure */
12+
/*
13+
* Flags for pg_malloc_extended and palloc_extended, deliberately named
14+
* the same as the backend flags.
15+
*/
16+
#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB)
17+
* not actually used for frontends */
18+
#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */
19+
#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */
20+
21+
/*
22+
* "Safe" memory allocation functions --- these exit(1) on failure
23+
* (except pg_malloc_extended with MCXT_ALLOC_NO_OOM)
24+
*/
1325
extern char *pg_strdup(const char *in);
1426
extern void *pg_malloc(size_t size);
1527
extern void *pg_malloc0(size_t size);
28+
extern void *pg_malloc_extended(size_t size, int flags);
1629
extern void *pg_realloc(void *pointer, size_t size);
1730
extern void pg_free(void *pointer);
1831

1932
/* Equivalent functions, deliberately named the same as backend functions */
2033
extern char *pstrdup(const char *in);
2134
extern void *palloc(Size size);
2235
extern void *palloc0(Size size);
36+
extern void *palloc_extended(Size size, int flags);
2337
extern void *repalloc(void *pointer, Size size);
2438
extern void pfree(void *pointer);
2539

src/include/utils/palloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ extern void *MemoryContextAllocExtended(MemoryContext context,
7676

7777
extern void *palloc(Size size);
7878
extern void *palloc0(Size size);
79+
extern void *palloc_extended(Size size, int flags);
7980
extern void *repalloc(void *pointer, Size size);
8081
extern void pfree(void *pointer);
8182

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