From 1ccf1890be605270d59f51f670c3bd54cf600205 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Mon, 30 Jul 2012 16:22:12 +0000 Subject: [PATCH] Statistics code. --- src/backend/utils/hash/chash.c | 60 ++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/backend/utils/hash/chash.c b/src/backend/utils/hash/chash.c index f44b65009f..bfcf809d36 100644 --- a/src/backend/utils/hash/chash.c +++ b/src/backend/utils/hash/chash.c @@ -158,10 +158,24 @@ typedef struct CHashTableData char *arena; /* arena */ /* - * This field will be different in each backend; the shared copy is + * These fields will be different in each backend; the shared copy is * unused. */ uint32 gc_next; /* next garbage list to reclaim */ + uint64 s_insert_retry; /* insert point concurrently updated */ + uint64 s_delete_retry; /* delete point concurrently updated */ + uint64 s_cleanup_scan; /* expunge-after-delete failed */ + uint64 s_scan_expunge_ok; /* scan did expunge */ + uint64 s_scan_expunge_fail; /* expunge failed */ + uint64 s_scan_restart; /* scan restarted */ + uint64 s_cleanup_expunge_ok; /* cleanup scan did expunge */ + uint64 s_cleanup_expunge_fail; /* cleanup scan expunge failed */ + uint64 s_cleanup_restart; /* cleanup scan restarted */ + uint64 s_allocate_pop_fail; /* freelist pop failed */ + uint64 s_gc_pop_fail; /* garbage list pop failed */ + uint64 s_gc_reclaim_retry; /* failed to return GC'd nodes */ + uint64 s_garbage_retry; /* failed to enqueue garbage */ + uint64 s_free_retry; /* failed to perform immediate free */ } CHashTableData; #define CHashTableGetRaw(table, offset) \ @@ -225,7 +239,7 @@ CHashBootstrap(CHashDescriptor *desc) uint32 bucket_shift; /* Allocate table and copy descriptor. */ - table = MemoryContextAlloc(TopMemoryContext, sizeof(CHashTableData)); + table = MemoryContextAllocZero(TopMemoryContext, sizeof(CHashTableData)); memcpy(&table->desc, desc, sizeof(CHashDescriptor)); /* Sanity checks. */ @@ -474,7 +488,10 @@ retry: nnew->next = scan.target; if (!__sync_bool_compare_and_swap(scan.pointer_to_target, scan.target, new)) + { + table->s_insert_retry++; goto retry; + } } /* Allow garbage collection for this bucket. */ @@ -536,6 +553,7 @@ CHashDelete(CHashTable table, void *entry) cleanup_scan = true; break; } + table->s_delete_retry++; } /* @@ -543,7 +561,10 @@ CHashDelete(CHashTable table, void *entry) * to make sure it's really gone. */ if (cleanup_scan) + { + table->s_cleanup_scan++; CHashBucketCleanup(table, &table->bucket[bucket], hashcode); + } /* Allow garbage collection for this bucket. */ CHashTableUnsuppressGC(); @@ -631,6 +652,7 @@ zap: * all non-deleted items (and possibly some deleted items) * that were present at the time we began the scan. */ + table->s_scan_expunge_ok++; CHashAddToGarbage(table, hashcode & table->bucket_mask, target); target = CHashPtrUnmark(next); @@ -658,9 +680,13 @@ zap: * have to be pretty unlucky to have it happen even twice in * a row. */ + table->s_scan_expunge_fail++; target = *pointer_to_target; if (CHashPtrIsMarked(target)) + { + table->s_scan_restart++; goto retry; + } continue; } } @@ -771,6 +797,7 @@ retry: CHashPtrUnmark(next))) { /* We removed the item. */ + table->s_cleanup_expunge_ok++; CHashAddToGarbage(table, hashcode & table->bucket_mask, target); target = CHashPtrUnmark(next); @@ -845,14 +872,18 @@ CHashAllocate(CHashTable table) pg_read_barrier_depends(); if (__sync_bool_compare_and_swap(b, new, n->un.gcnext)) return new; + table->s_allocate_pop_fail++; } /* If next garbage list is non-empty, empty it via compare-and-swap. */ table->gc_next = (table->gc_next + 1) % table->ngarbage; b = &table->garbage[table->gc_next]; garbage = *b; - if (!CHashPtrIsInvalid(garbage) && - __sync_bool_compare_and_swap(b, garbage, InvalidCHashPtr)) + if (CHashPtrIsInvalid(garbage)) + ; + else if (!__sync_bool_compare_and_swap(b, garbage, InvalidCHashPtr)) + ++table->s_gc_pop_fail; + else { uint64 chash_bucket; uint32 i; @@ -905,11 +936,14 @@ CHashAllocate(CHashTable table) /* Push reclaimed elements onto home free list. */ b = &table->freelist[f_home]; - do + for (;;) { oldhead = *b; n->un.gcnext = oldhead; - } while (!__sync_bool_compare_and_swap(b, oldhead, fhead)); + if (__sync_bool_compare_and_swap(b, oldhead, fhead)) + break; + ++table->s_gc_reclaim_retry; + } } /* Return the element we saved for ourselves. */ @@ -943,11 +977,14 @@ CHashAddToGarbage(CHashTable table, uint32 bucket, CHashPtr c) n = CHashTableGetNode(table, c); garbage = &table->garbage[garbage_bucket]; - do + while (1) { g = *garbage; n->un.gcnext = g; - } while (!__sync_bool_compare_and_swap(garbage, g, c)); + if (__sync_bool_compare_and_swap(garbage, g, c)) + break; + ++table->s_garbage_retry; + } } /* @@ -970,9 +1007,12 @@ CHashImmediateFree(CHashTable table, CHashPtr c) n = CHashTableGetNode(table, c); free = &table->freelist[f_home]; - do + for (;;) { f = *free; n->un.gcnext = f; - } while (!__sync_bool_compare_and_swap(free, f, c)); + if (__sync_bool_compare_and_swap(free, f, c)) + break; + ++table->s_free_retry; + } } -- 2.39.5