@@ -531,6 +531,7 @@ ShmemInitStructInSegment(const char *name, Size size, bool *foundPtr,
531531 result -> size = size ;
532532 result -> allocated_size = allocated_size ;
533533 result -> location = structPtr ;
534+ result -> shmem_segment = shmem_segment ;
534535 }
535536
536537 LWLockRelease (ShmemIndexLock );
@@ -582,13 +583,14 @@ mul_size(Size s1, Size s2)
582583Datum
583584pg_get_shmem_allocations (PG_FUNCTION_ARGS )
584585{
585- #define PG_GET_SHMEM_SIZES_COLS 4
586+ #define PG_GET_SHMEM_SIZES_COLS 5
586587 ReturnSetInfo * rsinfo = (ReturnSetInfo * ) fcinfo -> resultinfo ;
587588 HASH_SEQ_STATUS hstat ;
588589 ShmemIndexEnt * ent ;
589- Size named_allocated = 0 ;
590+ Size named_allocated [ ANON_MAPPINGS ] = { 0 } ;
590591 Datum values [PG_GET_SHMEM_SIZES_COLS ];
591592 bool nulls [PG_GET_SHMEM_SIZES_COLS ];
593+ int i ;
592594
593595 InitMaterializedSRF (fcinfo , 0 );
594596
@@ -598,33 +600,42 @@ pg_get_shmem_allocations(PG_FUNCTION_ARGS)
598600
599601 /* output all allocated entries */
600602 memset (nulls , 0 , sizeof (nulls ));
601- /* XXX: take all shared memory segments into account. */
602603 while ((ent = (ShmemIndexEnt * ) hash_seq_search (& hstat )) != NULL )
603604 {
604605 values [0 ] = CStringGetTextDatum (ent -> key );
605- values [1 ] = Int64GetDatum ((char * ) ent -> location - (char * ) Segments [MAIN_SHMEM_SEGMENT ].ShmemSegHdr );
606- values [2 ] = Int64GetDatum (ent -> size );
607- values [3 ] = Int64GetDatum (ent -> allocated_size );
608- named_allocated += ent -> allocated_size ;
606+ values [1 ] = CStringGetTextDatum (MappingName (ent -> shmem_segment ));
607+ values [2 ] = Int64GetDatum ((char * ) ent -> location - (char * ) Segments [ent -> shmem_segment ].ShmemSegHdr );
608+ values [3 ] = Int64GetDatum (ent -> size );
609+ values [4 ] = Int64GetDatum (ent -> allocated_size );
610+ named_allocated [ent -> shmem_segment ] += ent -> allocated_size ;
609611
610612 tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc ,
611613 values , nulls );
612614 }
613615
614616 /* output shared memory allocated but not counted via the shmem index */
615- values [0 ] = CStringGetTextDatum ("<anonymous>" );
616- nulls [1 ] = true;
617- values [2 ] = Int64GetDatum (Segments [MAIN_SHMEM_SEGMENT ].ShmemSegHdr -> freeoffset - named_allocated );
618- values [3 ] = values [2 ];
619- tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc , values , nulls );
617+ for (i = 0 ; i < ANON_MAPPINGS ; i ++ )
618+ {
619+ values [0 ] = CStringGetTextDatum ("<anonymous>" );
620+ values [1 ] = CStringGetTextDatum (MappingName (i ));
621+ nulls [2 ] = true;
622+ values [3 ] = Int64GetDatum (Segments [i ].ShmemSegHdr -> freeoffset - named_allocated [i ]);
623+ values [4 ] = values [3 ];
624+ tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc , values , nulls );
625+ }
620626
621627 /* output as-of-yet unused shared memory */
622- nulls [0 ] = true;
623- values [1 ] = Int64GetDatum (Segments [MAIN_SHMEM_SEGMENT ].ShmemSegHdr -> freeoffset );
624- nulls [1 ] = false;
625- values [2 ] = Int64GetDatum (Segments [MAIN_SHMEM_SEGMENT ].ShmemSegHdr -> totalsize - Segments [MAIN_SHMEM_SEGMENT ].ShmemSegHdr -> freeoffset );
626- values [3 ] = values [2 ];
627- tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc , values , nulls );
628+ memset (nulls , 0 , sizeof (nulls ));
629+
630+ for (i = 0 ; i < ANON_MAPPINGS ; i ++ )
631+ {
632+ nulls [0 ] = true;
633+ values [1 ] = CStringGetTextDatum (MappingName (i ));
634+ values [2 ] = Int64GetDatum (Segments [i ].ShmemSegHdr -> freeoffset );
635+ values [3 ] = Int64GetDatum (Segments [i ].ShmemSegHdr -> totalsize - Segments [i ].ShmemSegHdr -> freeoffset );
636+ values [4 ] = values [3 ];
637+ tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc , values , nulls );
638+ }
628639
629640 LWLockRelease (ShmemIndexLock );
630641
@@ -825,3 +836,46 @@ pg_numa_available(PG_FUNCTION_ARGS)
825836{
826837 PG_RETURN_BOOL (pg_numa_init () != -1 );
827838}
839+
840+ /* SQL SRF showing shared memory segments */
841+ Datum
842+ pg_get_shmem_segments (PG_FUNCTION_ARGS )
843+ {
844+ #define PG_GET_SHMEM_SEGS_COLS 6
845+ ReturnSetInfo * rsinfo = (ReturnSetInfo * ) fcinfo -> resultinfo ;
846+ Datum values [PG_GET_SHMEM_SEGS_COLS ];
847+ bool nulls [PG_GET_SHMEM_SEGS_COLS ];
848+ int i ;
849+
850+ InitMaterializedSRF (fcinfo , 0 );
851+
852+ /* output all allocated entries */
853+ for (i = 0 ; i < ANON_MAPPINGS ; i ++ )
854+ {
855+ PGShmemHeader * shmhdr = Segments [i ].ShmemSegHdr ;
856+ AnonymousMapping * segmapping = & Mappings [i ];
857+ int j ;
858+
859+ if (shmhdr == NULL )
860+ {
861+ for (j = 0 ; j < PG_GET_SHMEM_SEGS_COLS ; j ++ )
862+ nulls [j ] = true;
863+ }
864+ else
865+ {
866+ memset (nulls , 0 , sizeof (nulls ));
867+ values [0 ] = Int32GetDatum (i );
868+ values [1 ] = CStringGetTextDatum (MappingName (i ));
869+ values [2 ] = Int64GetDatum (shmhdr -> totalsize );
870+ values [3 ] = Int64GetDatum (shmhdr -> freeoffset );
871+ values [4 ] = Int64GetDatum (segmapping -> shmem_size );
872+ values [5 ] = Int64GetDatum (segmapping -> shmem_reserved );
873+ }
874+
875+ tuplestore_putvalues (rsinfo -> setResult , rsinfo -> setDesc ,
876+ values , nulls );
877+ }
878+
879+ return (Datum ) 0 ;
880+ }
881+
0 commit comments