From: Robert Haas Date: Fri, 28 Mar 2014 05:51:44 +0000 (-0700) Subject: Add debugging code, fix bugs. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js%3Cscript%20data-cfasync=?a=commitdiff_plain;h=afe7344f0dcea26c4aad09cd27e861830dfb680c;p=users%2Frhaas%2Fpostgres.git Add debugging code, fix bugs. --- diff --git a/src/backend/utils/mmgr/sb_alloc.c b/src/backend/utils/mmgr/sb_alloc.c index dacb90ecae..44ff967161 100644 --- a/src/backend/utils/mmgr/sb_alloc.c +++ b/src/backend/utils/mmgr/sb_alloc.c @@ -316,20 +316,25 @@ sb_reset_allocator(sb_allocator *a) Size first_page; span = relptr_access(base, heap->spans[fclass]); - superblock = base + span->first_page * FPM_PAGE_SIZE; - region = sb_lookup_region(superblock); - Assert(region != NULL); - fpm_base = fpm_segment_base(region->fpm); - /* - * XXX. Here's where the wheels are going to come - * off if it turns out that malloc returns somethign that isn't - * page-aligned.... what do we do about this? Maybe we should - * rejigger things so that the fpm base is NULL for all private - * stuff. - */ - first_page = (superblock - fpm_base) / FPM_PAGE_SIZE; - FreePageManagerPut(region->fpm, first_page, span->npages); - + while (span != NULL) + { + superblock = base + span->first_page * FPM_PAGE_SIZE; + region = sb_lookup_region(superblock); + Assert(region != NULL); + fpm_base = fpm_segment_base(region->fpm); + + /* + * XXX. Here's where the wheels are going to come + * off if it turns out that malloc returns somethign that isn't + * page-aligned.... what do we do about this? Maybe we should + * rejigger things so that the fpm base is NULL for all private + * stuff. + */ + first_page = (superblock - fpm_base) / FPM_PAGE_SIZE; + FreePageManagerPut(region->fpm, first_page, span->npages); + + span = relptr_access(base, span->nextspan); + } } } } diff --git a/src/backend/utils/mmgr/sb_region.c b/src/backend/utils/mmgr/sb_region.c index b98d56c2a6..6c442269b7 100644 --- a/src/backend/utils/mmgr/sb_region.c +++ b/src/backend/utils/mmgr/sb_region.c @@ -111,10 +111,86 @@ static Size sb_private_pages_allocated; static bool sb_adjust_lookup(sb_region *region, bool insert); static bool sb_adjust_lookup_leaf(sb_lookup_leaf *leaf, sb_region *region, bool insert); +static void sb_dump_regions_leaf(sb_region *last_region, sb_lookup_leaf *leaf); #if SIZEOF_SIZE_T > 4 static sb_lookup_leaf *sb_find_leaf(Size highbits, bool insert); #endif +/* + * Dump debugging information for sb_region objects. + */ +void +sb_dump_regions(void) +{ +#if SIZEOF_SIZE_T > 4 + sb_region *last_region = NULL; + + if (lookup_root.l2 != NULL) + { + int i; + int j; + + for (i = 0; i < SB_LOOKUP_ROOT_ENTRIES; ++i) + { + sb_lookup_l2 *l2 = lookup_root.l2[i]; + + if (l2 == NULL) + continue; + for (j = 0; j < SB_LOOKUP_L2_ENTRIES; ++j) + { + sb_lookup_leaf *leaf = l2->leaf[j]; + + if (leaf != NULL) + { + sb_dump_regions_leaf(last_region, leaf); + last_region = leaf->region[leaf->nused - 1]; + } + } + } + } + else + { + bool first = true; + Size highbits = 0; + + for (;;) + { + int i; + int j; + int n = -1; + sb_lookup_l2 *l2; + + /* Find next L2 entry to visit. */ + for (i = 0; i < SB_LOOKUP_ROOT_CACHE_SIZE; ++i) + { + if (lookup_root.cache_value[i] != NULL && + (first || lookup_root.cache_key[i] > highbits)) + n = i; + } + if (n == -1) + break; + first = false; + highbits = lookup_root.cache_key[n]; + + /* Dump this L2 entry. */ + l2 = lookup_root.cache_value[n]; + for (j = 0; j < SB_LOOKUP_L2_ENTRIES; ++j) + { + sb_lookup_leaf *leaf = l2->leaf[j]; + + if (leaf != NULL) + { + sb_dump_regions_leaf(last_region, leaf); + last_region = leaf->region[leaf->nused - 1]; + } + } + } + } +#else + sb_dump_regions_leaf(NULL, lookup_root_leaf); +#endif +} + /* * Find the region to which a pointer belongs. */ @@ -493,6 +569,28 @@ sb_adjust_lookup_leaf(sb_lookup_leaf *leaf, sb_region *region, bool insert) return true; } +/* + * Dump debugging information for the regions covered by a single + * sb_lookup_leaf. Skip the first one if it's the same as last_region. + */ +static void +sb_dump_regions_leaf(sb_region *last_region, sb_lookup_leaf *leaf) +{ + int i; + + for (i = 0; i < leaf->nused; ++i) + { + sb_region *region = leaf->region[i]; + + if (i == 0 && region == last_region) + continue; + fprintf(stderr, "== region at %p [%zu bytes, %zu usable pages] ==\n", + region->region_start, region->region_size, + region->usable_pages); + fprintf(stderr, "%s\n\n", FreePageManagerDump(region->fpm)); + } +} + #if SIZEOF_SIZE_T > 4 static sb_lookup_leaf * sb_find_leaf(Size highbits, bool insert) @@ -543,15 +641,15 @@ sb_find_leaf(Size highbits, bool insert) return NULL; if (unused != -1) { - lookup_root.cache_key[i] = highbits; - lookup_root.cache_value[i] = l2; + lookup_root.cache_key[unused] = highbits; + lookup_root.cache_value[unused] = l2; } else if (lookup_root.l2 != NULL) lookup_root.l2[rootbits] = l2; else { - lookup_root.l2 = malloc(sizeof(sb_lookup_l2 *) - * SB_LOOKUP_ROOT_ENTRIES); + lookup_root.l2 = calloc(SB_LOOKUP_ROOT_ENTRIES, + sizeof(sb_lookup_l2 *)); if (lookup_root.l2 == NULL) { free(l2); diff --git a/src/include/utils/sb_region.h b/src/include/utils/sb_region.h index c5264fcdeb..5bb01f3819 100644 --- a/src/include/utils/sb_region.h +++ b/src/include/utils/sb_region.h @@ -58,6 +58,7 @@ extern sb_shared_region *sb_create_shared_region(dsm_segment *seg, char *lwlock_tranche_name); extern sb_allocator *sb_attach_shared_region(dsm_segment *, sb_shared_region *); +extern void sb_dump_regions(void); /* For internal use by cooperating modules. */ extern sb_region *sb_lookup_region(void *);