@@ -642,18 +642,39 @@ dsa_pin_mapping(dsa_area *area)
642
642
/*
643
643
* Allocate memory in this storage area. The return value is a dsa_pointer
644
644
* 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.
647
662
*/
648
663
dsa_pointer
649
- dsa_allocate (dsa_area * area , Size size )
664
+ dsa_allocate_extended (dsa_area * area , Size size , int flags )
650
665
{
651
666
uint16 size_class ;
652
667
dsa_pointer start_pointer ;
653
668
dsa_segment_map * segment_map ;
669
+ dsa_pointer result ;
654
670
655
671
Assert (size > 0 );
656
672
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
+
657
678
/*
658
679
* If bigger than the largest size class, just grab a run of pages from
659
680
* the free page manager, instead of allocating an object from a pool.
@@ -684,6 +705,14 @@ dsa_allocate(dsa_area *area, Size size)
684
705
/* Can't make any more segments: game over. */
685
706
LWLockRelease (DSA_AREA_LOCK (area ));
686
707
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 )));
687
716
return InvalidDsaPointer ;
688
717
}
689
718
@@ -710,6 +739,10 @@ dsa_allocate(dsa_area *area, Size size)
710
739
segment_map -> pagemap [first_page ] = span_pointer ;
711
740
LWLockRelease (DSA_SCLASS_LOCK (area , DSA_SCLASS_SPAN_LARGE ));
712
741
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
+
713
746
return start_pointer ;
714
747
}
715
748
@@ -748,27 +781,28 @@ dsa_allocate(dsa_area *area, Size size)
748
781
Assert (size <= dsa_size_classes [size_class ]);
749
782
Assert (size_class == 0 || size > dsa_size_classes [size_class - 1 ]);
750
783
751
- /*
752
- * Attempt to allocate an object from the appropriate pool. This might
753
- * return InvalidDsaPointer if there's no space available.
754
- */
755
- return alloc_object (area , size_class );
756
- }
784
+ /* Attempt to allocate an object from the appropriate pool. */
785
+ result = alloc_object (area , size_class );
757
786
758
- /*
759
- * As dsa_allocate, but zeroes the allocated memory.
760
- */
761
- dsa_pointer
762
- dsa_allocate0 (dsa_area * area , Size size )
763
- {
764
- dsa_pointer dp ;
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
+ return InvalidDsaPointer ;
799
+ }
766
800
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 );
770
804
771
- return dp ;
805
+ return result ;
772
806
}
773
807
774
808
/*
0 commit comments