BlockAllocatorStats
authorRobert Haas <rhaas@postgresql.org>
Thu, 12 Jun 2014 20:37:10 +0000 (16:37 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 12 Jun 2014 20:37:10 +0000 (16:37 -0400)
contrib/test_balloc/test_balloc.c
src/backend/utils/mmgr/balloc.c
src/include/utils/balloc.h

index eedeb7e473a010446f043e705f6db95ad0c15eba..890d812f322da3c15617b20304d64ec614229e9c 100644 (file)
@@ -51,16 +51,10 @@ alloc(PG_FUNCTION_ARGS)
                p = MemoryContextAlloc(context, size);
                *p = i;
        }
+       MemoryContextStats(context);
+       MemoryContextDelete(context);
        if (usenew)
-       {
-               BlockAllocatorReset(context);
                DumpAllocatorRegions();
-       }
-       else
-       {
-               MemoryContextStats(context);
-               MemoryContextDelete(context);
-       }
 
        PG_RETURN_VOID();
 }
@@ -100,16 +94,10 @@ alloc_list(PG_FUNCTION_ARGS)
                pfree(h);
                h = p;
        }
+       MemoryContextStats(context);
+       MemoryContextDelete(context);
        if (usenew)
-       {
                DumpAllocatorRegions();
-               BlockAllocatorReset(context);
-       }
-       else
-       {
-               MemoryContextStats(context);
-               MemoryContextDelete(context);
-       }
 
        PG_RETURN_VOID();
 }
index ce56b0c249588b61eab6dbded997608c74c038e8..5ae4b50bf277a822115010c8d7f694c40ab683f6 100644 (file)
@@ -195,7 +195,7 @@ static MemoryContextMethods BlockAllocatorMethods = {
        BlockAllocatorDelete,
        NULL,   /* chunk space: What do we do here?  Existing API doesn't work. */
        NULL, /* XXX BlockAllocatorIsEmpty, */
-       NULL  /* XXX BlockAllocatorStats */
+       BlockAllocatorStats
 #ifdef MEMORY_CONTEXT_CHECKING
        ,NULL /* XXX BlockAllocatorCheck */
 #endif
@@ -810,6 +810,77 @@ BlockAllocatorDelete(MemoryContext context)
        BlockAllocatorReset(context);
 }
 
+/*
+ * Display memory consumption statistics for a context.
+ */
+void
+BlockAllocatorStats(MemoryContext context, int level)
+{
+       BlockAllocatorContext *bcontext = (BlockAllocatorContext *) context;
+       Size            nblocks_normal = 0;
+       Size            nblocks_spans = 0;
+       Size            freespace_normal = 0;
+       Size            freespace_spans = 0;
+       Size            totalspace_normal = 0;
+       Size            totalspace_spans = 0;
+       char   *base = NULL;
+       int             heapno;
+       int             i;
+
+       Assert(IsA(bcontext, BlockAllocatorContext));
+
+       /* XXX. Set base appropriately if this is a shared context. */
+
+       for (heapno = 0; heapno < BA_NUM_SIZE_CLASSES; ++heapno)
+       {
+               BlockAllocatorHeap *heap = &bcontext->heaps[heapno];
+               int             fclass;
+
+               for (fclass = 0; fclass < BA_FULLNESS_CLASSES; ++fclass)
+               {
+                       char *block;
+                       BlockAllocatorSpan *span;
+                       uint16  size_class;
+
+                       span = relptr_access(base, heap->spans[fclass]);
+                       while (span != NULL)
+                       {
+                               block = relptr_access(base, span->start);
+
+                               size_class = span->size_class;
+                               if (size_class == BA_SCLASS_BLOCK_OF_SPANS)
+                               {
+                                       ++nblocks_spans;
+                                       freespace_spans += sizeof(BlockAllocatorSpan) * span->nallocatable;
+                                       totalspace_spans += FPM_PAGE_SIZE;
+                               }
+                               else if (size_class == BA_SCLASS_SPAN_LARGE)
+                               {
+                                       ++nblocks_normal;
+                                       totalspace_normal = FPM_PAGE_SIZE * span->npages;
+                               }
+                               else
+                               {
+                                       ++nblocks_normal;
+                                       freespace_normal += balloc_size_classes[size_class] * span->nallocatable;
+                                       totalspace_normal += BA_SUPERBLOCK_SIZE;
+                               }
+
+                               span = relptr_access(base, span->nextspan);
+                       }
+               }
+       }
+
+       for (i = 0; i < level; i++)
+               fprintf(stderr, "  ");
+
+       fprintf(stderr,
+                       "%s: %zu bytes in %zu normal blocks (%zu free); %zu bytes in %zu span blocks (%zu free)\n",
+                       bcontext->header.name,
+                       totalspace_normal, nblocks_normal, freespace_normal,
+                       totalspace_spans, nblocks_spans, freespace_spans);
+}
+
 /*
  * Allocate an object of the requested size class from the given allocator.
  * If necessary, steal or create another block.
index 983a06313bad16b0d7a22d16d528bfb9c0afee3d..4d07e8a8e9d168fc1f6eca170bdb8b937d150d69 100644 (file)
@@ -39,7 +39,7 @@ extern Size BlockAllocatorGetAllocSpace(Size size);   /* EXTRA FUNCTION */
 extern MemoryContext BlockAllocatorGetChunkContext(struct AllocatorRegion *,
                                                                                                   void *ptr);
 /* IS_EMPTY IS MISSING! */
-/* STATS IS MISSING! */
+extern void BlockAllocatorStats(MemoryContext, int);
 /* CHECK IS MISSING */
 
 #endif         /* BALLOC_H */