Skip to content

Commit 9c911ec

Browse files
committed
Make some minor improvements in memory-context infrastructure.
We lack a version of repalloc() that supports MCXT_ALLOC_NO_OOM semantics, so invent repalloc_extended() with the usual set of flags. repalloc_huge() becomes a legacy wrapper for that. Also, fix dynahash.c so that it can support HASH_ENTER_NULL requests when using the default palloc-based allocator. The only reason it didn't do that already was the lack of the MCXT_ALLOC_NO_OOM option when that code was written, ages ago. While here, simplify a few overcomplicated tests in mcxt.c. Discussion: https://postgr.es/m/2982579.1662416866@sss.pgh.pa.us
1 parent 1b11561 commit 9c911ec

File tree

3 files changed

+56
-42
lines changed

3 files changed

+56
-42
lines changed

src/backend/utils/hash/dynahash.c

+4-9
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ static void *
289289
DynaHashAlloc(Size size)
290290
{
291291
Assert(MemoryContextIsValid(CurrentDynaHashCxt));
292-
return MemoryContextAlloc(CurrentDynaHashCxt, size);
292+
return MemoryContextAllocExtended(CurrentDynaHashCxt, size,
293+
MCXT_ALLOC_NO_OOM);
293294
}
294295

295296

@@ -939,9 +940,7 @@ calc_bucket(HASHHDR *hctl, uint32 hash_val)
939940
*
940941
* HASH_ENTER will normally ereport a generic "out of memory" error if
941942
* it is unable to create a new entry. The HASH_ENTER_NULL operation is
942-
* the same except it will return NULL if out of memory. Note that
943-
* HASH_ENTER_NULL cannot be used with the default palloc-based allocator,
944-
* since palloc internally ereports on out-of-memory.
943+
* the same except it will return NULL if out of memory.
945944
*
946945
* If foundPtr isn't NULL, then *foundPtr is set true if we found an
947946
* existing entry in the table, false otherwise. This is needed in the
@@ -1084,12 +1083,8 @@ hash_search_with_hash_value(HTAB *hashp,
10841083
}
10851084
return NULL;
10861085

1087-
case HASH_ENTER_NULL:
1088-
/* ENTER_NULL does not work with palloc-based allocator */
1089-
Assert(hashp->alloc != DynaHashAlloc);
1090-
/* FALL THRU */
1091-
10921086
case HASH_ENTER:
1087+
case HASH_ENTER_NULL:
10931088
/* Return existing element if found, else create one */
10941089
if (currBucket != NULL)
10951090
return (void *) ELEMENTKEY(currBucket);

src/backend/utils/mmgr/mcxt.c

+50-33
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,8 @@ MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
11141114
AssertArg(MemoryContextIsValid(context));
11151115
AssertNotInCriticalSection(context);
11161116

1117-
if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
1118-
((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
1117+
if (!((flags & MCXT_ALLOC_HUGE) != 0 ? AllocHugeSizeIsValid(size) :
1118+
AllocSizeIsValid(size)))
11191119
elog(ERROR, "invalid memory alloc request size %zu", size);
11201120

11211121
context->isReset = false;
@@ -1269,8 +1269,8 @@ palloc_extended(Size size, int flags)
12691269
AssertArg(MemoryContextIsValid(context));
12701270
AssertNotInCriticalSection(context);
12711271

1272-
if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
1273-
((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
1272+
if (!((flags & MCXT_ALLOC_HUGE) != 0 ? AllocHugeSizeIsValid(size) :
1273+
AllocSizeIsValid(size)))
12741274
elog(ERROR, "invalid memory alloc request size %zu", size);
12751275

12761276
context->isReset = false;
@@ -1351,6 +1351,50 @@ repalloc(void *pointer, Size size)
13511351
return ret;
13521352
}
13531353

1354+
/*
1355+
* repalloc_extended
1356+
* Adjust the size of a previously allocated chunk,
1357+
* with HUGE and NO_OOM options.
1358+
*/
1359+
void *
1360+
repalloc_extended(void *pointer, Size size, int flags)
1361+
{
1362+
#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1363+
MemoryContext context = GetMemoryChunkContext(pointer);
1364+
#endif
1365+
void *ret;
1366+
1367+
if (!((flags & MCXT_ALLOC_HUGE) != 0 ? AllocHugeSizeIsValid(size) :
1368+
AllocSizeIsValid(size)))
1369+
elog(ERROR, "invalid memory alloc request size %zu", size);
1370+
1371+
AssertNotInCriticalSection(context);
1372+
1373+
/* isReset must be false already */
1374+
Assert(!context->isReset);
1375+
1376+
ret = MCXT_METHOD(pointer, realloc) (pointer, size);
1377+
if (unlikely(ret == NULL))
1378+
{
1379+
if ((flags & MCXT_ALLOC_NO_OOM) == 0)
1380+
{
1381+
MemoryContext cxt = GetMemoryChunkContext(pointer);
1382+
1383+
MemoryContextStats(TopMemoryContext);
1384+
ereport(ERROR,
1385+
(errcode(ERRCODE_OUT_OF_MEMORY),
1386+
errmsg("out of memory"),
1387+
errdetail("Failed on request of size %zu in memory context \"%s\".",
1388+
size, cxt->name)));
1389+
}
1390+
return NULL;
1391+
}
1392+
1393+
VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1394+
1395+
return ret;
1396+
}
1397+
13541398
/*
13551399
* MemoryContextAllocHuge
13561400
* Allocate (possibly-expansive) space within the specified context.
@@ -1394,35 +1438,8 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
13941438
void *
13951439
repalloc_huge(void *pointer, Size size)
13961440
{
1397-
#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1398-
MemoryContext context = GetMemoryChunkContext(pointer);
1399-
#endif
1400-
void *ret;
1401-
1402-
if (!AllocHugeSizeIsValid(size))
1403-
elog(ERROR, "invalid memory alloc request size %zu", size);
1404-
1405-
AssertNotInCriticalSection(context);
1406-
1407-
/* isReset must be false already */
1408-
Assert(!context->isReset);
1409-
1410-
ret = MCXT_METHOD(pointer, realloc) (pointer, size);
1411-
if (unlikely(ret == NULL))
1412-
{
1413-
MemoryContext cxt = GetMemoryChunkContext(pointer);
1414-
1415-
MemoryContextStats(TopMemoryContext);
1416-
ereport(ERROR,
1417-
(errcode(ERRCODE_OUT_OF_MEMORY),
1418-
errmsg("out of memory"),
1419-
errdetail("Failed on request of size %zu in memory context \"%s\".",
1420-
size, cxt->name)));
1421-
}
1422-
1423-
VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1424-
1425-
return ret;
1441+
/* this one seems not worth its own implementation */
1442+
return repalloc_extended(pointer, size, MCXT_ALLOC_HUGE);
14261443
}
14271444

14281445
/*

src/include/utils/palloc.h

+2
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ extern void *palloc(Size size);
7878
extern void *palloc0(Size size);
7979
extern void *palloc_extended(Size size, int flags);
8080
extern pg_nodiscard void *repalloc(void *pointer, Size size);
81+
extern pg_nodiscard void *repalloc_extended(void *pointer,
82+
Size size, int flags);
8183
extern void pfree(void *pointer);
8284

8385
/*

0 commit comments

Comments
 (0)