Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit16be2fd

Browse files
committed
Make dsa_allocate interface more like MemoryContextAlloc.
A new function dsa_allocate_extended now takes flags which indicatethat huge allocations should be permitted, that out-of-memoryconditions should not throw an error, and/or that the returned memoryshould be zero-filled, just like MemoryContextAllocateExtended.Commit9acb855, which addeddsa_allocate0, was broken because it failed to account for thepossibility that dsa_allocate() might return InvalidDsaPointer.This fixes that problem along the way.Thomas Munro, with some comment changes by me.Discussion:http://postgr.es/m/CA+Tgmobt7CcF_uQP2UQwWmu4K9qCHehMJP9_9m1urwP8hbOeHQ@mail.gmail.com
1 parent1a16af8 commit16be2fd

File tree

2 files changed

+69
-23
lines changed

2 files changed

+69
-23
lines changed

‎src/backend/utils/mmgr/dsa.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -642,18 +642,39 @@ dsa_pin_mapping(dsa_area *area)
642642
/*
643643
* Allocate memory in this storage area. The return value is a dsa_pointer
644644
* that can be passed to other processes, and converted to a local pointer
645-
* with dsa_get_address. If no memory is available, returns
646-
* InvalidDsaPointer.
645+
* with dsa_get_address. 'flags' is a bitmap which should be constructed
646+
* from the following values:
647+
*
648+
* DSA_ALLOC_HUGE allows allocations >= 1GB. Otherwise, such allocations
649+
* will result in an ERROR.
650+
*
651+
* DSA_ALLOC_NO_OOM causes this function to return InvalidDsaPointer when
652+
* no memory is available or a size limit establed by set_dsa_size_limit
653+
* would be exceeded. Otherwise, such allocations will result in an ERROR.
654+
*
655+
* DSA_ALLOC_ZERO causes the allocated memory to be zeroed. Otherwise, the
656+
* contents of newly-allocated memory are indeterminate.
657+
*
658+
* These flags correspond to similarly named flags used by
659+
* MemoryContextAllocExtended(). See also the macros dsa_allocate and
660+
* dsa_allocate0 which expand to a call to this function with commonly used
661+
* flags.
647662
*/
648663
dsa_pointer
649-
dsa_allocate(dsa_area*area,Sizesize)
664+
dsa_allocate_extended(dsa_area*area,Sizesize,intflags)
650665
{
651666
uint16size_class;
652667
dsa_pointerstart_pointer;
653668
dsa_segment_map*segment_map;
669+
dsa_pointerresult;
654670

655671
Assert(size>0);
656672

673+
/* Sanity check on huge individual allocation size. */
674+
if (((flags&DSA_ALLOC_HUGE)!=0&& !AllocHugeSizeIsValid(size))||
675+
((flags&DSA_ALLOC_HUGE)==0&& !AllocSizeIsValid(size)))
676+
elog(ERROR,"invalid DSA memory alloc request size %zu",size);
677+
657678
/*
658679
* If bigger than the largest size class, just grab a run of pages from
659680
* the free page manager, instead of allocating an object from a pool.
@@ -684,6 +705,14 @@ dsa_allocate(dsa_area *area, Size size)
684705
/* Can't make any more segments: game over. */
685706
LWLockRelease(DSA_AREA_LOCK(area));
686707
dsa_free(area,span_pointer);
708+
709+
/* Raise error unless asked not to. */
710+
if ((flags&MCXT_ALLOC_NO_OOM)==0)
711+
ereport(ERROR,
712+
(errcode(ERRCODE_OUT_OF_MEMORY),
713+
errmsg("out of memory"),
714+
errdetail("Failed on DSA request of size %zu.",
715+
size)));
687716
returnInvalidDsaPointer;
688717
}
689718

@@ -710,6 +739,10 @@ dsa_allocate(dsa_area *area, Size size)
710739
segment_map->pagemap[first_page]=span_pointer;
711740
LWLockRelease(DSA_SCLASS_LOCK(area,DSA_SCLASS_SPAN_LARGE));
712741

742+
/* Zero-initialize the memory if requested. */
743+
if ((flags&DSA_ALLOC_ZERO)!=0)
744+
memset(dsa_get_address(area,start_pointer),0,size);
745+
713746
returnstart_pointer;
714747
}
715748

@@ -748,27 +781,28 @@ dsa_allocate(dsa_area *area, Size size)
748781
Assert(size <=dsa_size_classes[size_class]);
749782
Assert(size_class==0||size>dsa_size_classes[size_class-1]);
750783

751-
/*
752-
* Attempt to allocate an object from the appropriate pool. This might
753-
* return InvalidDsaPointer if there's no space available.
754-
*/
755-
returnalloc_object(area,size_class);
756-
}
784+
/* Attempt to allocate an object from the appropriate pool. */
785+
result=alloc_object(area,size_class);
757786

758-
/*
759-
* As dsa_allocate, but zeroes the allocated memory.
760-
*/
761-
dsa_pointer
762-
dsa_allocate0(dsa_area*area,Sizesize)
763-
{
764-
dsa_pointerdp;
765-
char*object;
787+
/* Check for failure to allocate. */
788+
if (!DsaPointerIsValid(result))
789+
{
790+
/* Raise error unless asked not to. */
791+
if ((flags&DSA_ALLOC_NO_OOM)==0)
792+
{
793+
ereport(ERROR,
794+
(errcode(ERRCODE_OUT_OF_MEMORY),
795+
errmsg("out of memory"),
796+
errdetail("Failed on DSA request of size %zu.",size)));
797+
}
798+
returnInvalidDsaPointer;
799+
}
766800

767-
dp=dsa_allocate(area,size);
768-
object=dsa_get_address(area,dp);
769-
memset(object,0,size);
801+
/* Zero-initialize the memory if requested. */
802+
if ((flags&DSA_ALLOC_ZERO)!=0)
803+
memset(dsa_get_address(area,result),0,size);
770804

771-
returndp;
805+
returnresult;
772806
}
773807

774808
/*

‎src/include/utils/dsa.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,25 @@ typedef pg_atomic_uint64 dsa_pointer_atomic;
7171
#defineDSA_POINTER_FORMAT "%016" INT64_MODIFIER "x"
7272
#endif
7373

74+
/* Flags for dsa_allocate_extended. */
75+
#defineDSA_ALLOC_HUGE0x01/* allow huge allocation (> 1 GB) */
76+
#defineDSA_ALLOC_NO_OOM0x02/* no failure if out-of-memory */
77+
#defineDSA_ALLOC_ZERO0x04/* zero allocated memory */
78+
7479
/* A sentinel value for dsa_pointer used to indicate failure to allocate. */
7580
#defineInvalidDsaPointer ((dsa_pointer) 0)
7681

7782
/* Check if a dsa_pointer value is valid. */
7883
#defineDsaPointerIsValid(x) ((x) != InvalidDsaPointer)
7984

85+
/* Allocate uninitialized memory with error on out-of-memory. */
86+
#definedsa_allocate(area,size) \
87+
dsa_allocate_extended(area, size, 0)
88+
89+
/* Allocate zero-initialized memory with error on out-of-memory. */
90+
#definedsa_allocate0(area,size) \
91+
dsa_allocate_extended(area, size, DSA_ALLOC_ZERO)
92+
8093
/*
8194
* The type used for dsa_area handles. dsa_handle values can be shared with
8295
* other processes, so that they can attach to them. This provides a way to
@@ -105,8 +118,7 @@ extern void dsa_unpin(dsa_area *area);
105118
externvoiddsa_set_size_limit(dsa_area*area,Sizelimit);
106119
externSizedsa_minimum_size(void);
107120
externdsa_handledsa_get_handle(dsa_area*area);
108-
externdsa_pointerdsa_allocate(dsa_area*area,Sizesize);
109-
externdsa_pointerdsa_allocate0(dsa_area*area,Sizesize);
121+
externdsa_pointerdsa_allocate_extended(dsa_area*area,Sizesize,intflags);
110122
externvoiddsa_free(dsa_area*area,dsa_pointerdp);
111123
externvoid*dsa_get_address(dsa_area*area,dsa_pointerdp);
112124
externvoiddsa_trim(dsa_area*area);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp