Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1gCFbr-00030o-Bl for pgsql-hackers@arkaria.postgresql.org; Tue, 16 Oct 2018 03:01:27 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gCFbp-0007to-PX for pgsql-hackers@arkaria.postgresql.org; Tue, 16 Oct 2018 03:01:25 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1gCFbp-0007th-Ei for pgsql-hackers@lists.postgresql.org; Tue, 16 Oct 2018 03:01:25 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1gCFbi-00015k-MG for pgsql-hackers@postgresql.org; Tue, 16 Oct 2018 03:01:24 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id w9G31CSQ031563; Mon, 15 Oct 2018 23:01:12 -0400 From: Tom Lane To: Andres Freund cc: pgsql-hackers@postgresql.org, Thomas Munro Subject: Re: Large writable variables In-reply-to: <20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de> References: <20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de> Comments: In-reply-to Andres Freund message dated "Mon, 15 Oct 2018 13:07:54 -0700" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <31510.1539658813.0@sss.pgh.pa.us> Date: Mon, 15 Oct 2018 23:01:12 -0400 Message-ID: <31562.1539658872@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <31510.1539658813.1@sss.pgh.pa.us> Andres Freund writes: > top unitialized allocations: > 0000000008435040 0000000000085280 b DCHCache > 0000000008391168 0000000000043840 b NUMCache Here's a patch to improve that situation. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="alloc-formatting-cache-only-as-needed.patch"; charset="us-ascii" Content-ID: <31510.1539658813.2@sss.pgh.pa.us> Content-Description: alloc-formatting-cache-only-as-needed.patch Content-Transfer-Encoding: quoted-printable diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/fo= rmatting.c index b3ff133..43a0307 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -93,6 +93,7 @@ #include "utils/float.h" #include "utils/formatting.h" #include "utils/int8.h" +#include "utils/memutils.h" #include "utils/numeric.h" #include "utils/pg_locale.h" = @@ -385,12 +386,12 @@ typedef struct } NUMCacheEntry; = /* global cache for date/time format pictures */ -static DCHCacheEntry DCHCache[DCH_CACHE_ENTRIES]; +static DCHCacheEntry *DCHCache[DCH_CACHE_ENTRIES]; static int n_DCHCache =3D 0; /* current number of entries */ static int DCHCounter =3D 0; /* aging-event counter */ = /* global cache for number format pictures */ -static NUMCacheEntry NUMCache[NUM_CACHE_ENTRIES]; +static NUMCacheEntry *NUMCache[NUM_CACHE_ENTRIES]; static int n_NUMCache =3D 0; /* current number of entries */ static int NUMCounter =3D 0; /* aging-event counter */ = @@ -3368,13 +3369,13 @@ DCH_cache_getnew(const char *str) { DCHCacheEntry *ent; = - /* counter overflow check - paranoia? */ + /* handle counter overflow by resetting all ages */ if (DCHCounter >=3D (INT_MAX - DCH_CACHE_ENTRIES)) { DCHCounter =3D 0; = - for (ent =3D DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++) - ent->age =3D (++DCHCounter); + for (int i =3D 0; i < n_DCHCache; i++) + DCHCache[i]->age =3D (++DCHCounter); } = /* @@ -3382,15 +3383,16 @@ DCH_cache_getnew(const char *str) */ if (n_DCHCache >=3D DCH_CACHE_ENTRIES) { - DCHCacheEntry *old =3D DCHCache + 0; + DCHCacheEntry *old =3D DCHCache[0]; = #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache); #endif if (old->valid) { - for (ent =3D DCHCache + 1; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++= ) + for (int i =3D 1; i < DCH_CACHE_ENTRIES; i++) { + ent =3D DCHCache[i]; if (!ent->valid) { old =3D ent; @@ -3414,7 +3416,9 @@ DCH_cache_getnew(const char *str) #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "NEW (%d)", n_DCHCache); #endif - ent =3D DCHCache + n_DCHCache; + Assert(DCHCache[n_DCHCache] =3D=3D NULL); + DCHCache[n_DCHCache] =3D ent =3D (DCHCacheEntry *) + MemoryContextAllocZero(TopMemoryContext, sizeof(DCHCacheEntry)); ent->valid =3D false; StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1); ent->age =3D (++DCHCounter); @@ -3428,20 +3432,19 @@ DCH_cache_getnew(const char *str) static DCHCacheEntry * DCH_cache_search(const char *str) { - int i; - DCHCacheEntry *ent; - - /* counter overflow check - paranoia? */ + /* handle counter overflow by resetting all ages */ if (DCHCounter >=3D (INT_MAX - DCH_CACHE_ENTRIES)) { DCHCounter =3D 0; = - for (ent =3D DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++) - ent->age =3D (++DCHCounter); + for (int i =3D 0; i < n_DCHCache; i++) + DCHCache[i]->age =3D (++DCHCounter); } = - for (i =3D 0, ent =3D DCHCache; i < n_DCHCache; i++, ent++) + for (int i =3D 0; i < n_DCHCache; i++) { + DCHCacheEntry *ent =3D DCHCache[i]; + if (ent->valid && strcmp(ent->str, str) =3D=3D 0) { ent->age =3D (++DCHCounter); @@ -4047,13 +4050,13 @@ NUM_cache_getnew(const char *str) { NUMCacheEntry *ent; = - /* counter overflow check - paranoia? */ + /* handle counter overflow by resetting all ages */ if (NUMCounter >=3D (INT_MAX - NUM_CACHE_ENTRIES)) { NUMCounter =3D 0; = - for (ent =3D NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++) - ent->age =3D (++NUMCounter); + for (int i =3D 0; i < n_NUMCache; i++) + NUMCache[i]->age =3D (++NUMCounter); } = /* @@ -4061,15 +4064,16 @@ NUM_cache_getnew(const char *str) */ if (n_NUMCache >=3D NUM_CACHE_ENTRIES) { - NUMCacheEntry *old =3D NUMCache + 0; + NUMCacheEntry *old =3D NUMCache[0]; = #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "Cache is full (%d)", n_NUMCache); #endif if (old->valid) { - for (ent =3D NUMCache + 1; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++= ) + for (int i =3D 1; i < NUM_CACHE_ENTRIES; i++) { + ent =3D NUMCache[i]; if (!ent->valid) { old =3D ent; @@ -4093,7 +4097,9 @@ NUM_cache_getnew(const char *str) #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "NEW (%d)", n_NUMCache); #endif - ent =3D NUMCache + n_NUMCache; + Assert(NUMCache[n_NUMCache] =3D=3D NULL); + NUMCache[n_NUMCache] =3D ent =3D (NUMCacheEntry *) + MemoryContextAllocZero(TopMemoryContext, sizeof(NUMCacheEntry)); ent->valid =3D false; StrNCpy(ent->str, str, NUM_CACHE_SIZE + 1); ent->age =3D (++NUMCounter); @@ -4107,20 +4113,19 @@ NUM_cache_getnew(const char *str) static NUMCacheEntry * NUM_cache_search(const char *str) { - int i; - NUMCacheEntry *ent; - - /* counter overflow check - paranoia? */ + /* handle counter overflow by resetting all ages */ if (NUMCounter >=3D (INT_MAX - NUM_CACHE_ENTRIES)) { NUMCounter =3D 0; = - for (ent =3D NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++) - ent->age =3D (++NUMCounter); + for (int i =3D 0; i < n_NUMCache; i++) + NUMCache[i]->age =3D (++NUMCounter); } = - for (i =3D 0, ent =3D NUMCache; i < n_NUMCache; i++, ent++) + for (int i =3D 0; i < n_NUMCache; i++) { + NUMCacheEntry *ent =3D NUMCache[i]; + if (ent->valid && strcmp(ent->str, str) =3D=3D 0) { ent->age =3D (++NUMCounter); ------- =_aaaaaaaaaa0--