This patch changes pgstat.c to use palloc(), AllocateFile() and
FreeFile() rather than malloc(), fopen() and fclose(), respectively.
I changed more_tabstat_space() (which is invoked at various times
indirectly throughout the backend) to allocate memory in its own private
memory context, rather than use malloc() -- we can't just use
CurrentMemoryContext because that may not be sufficiently long-lived.
Barring any objections I intend to apply this to HEAD tomorrow.
-Neil
--- src/backend/postmaster/pgstat.c
+++ src/backend/postmaster/pgstat.c
@@ -42,6 +42,7 @@
#include "miscadmin.h"
#include "postmaster/postmaster.h"
#include "storage/backendid.h"
+#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
#include "storage/pmsignal.h"
@@ -118,6 +119,7 @@
static bool pgStatRunningInCollector = FALSE;
+static MemoryContext tabstatCxt = NULL;
static int pgStatTabstatAlloc = 0;
static int pgStatTabstatUsed = 0;
static PgStat_MsgTabstat **pgStatTabstatMessages = NULL;
@@ -682,7 +683,7 @@
/* --
* pgstat_report_activity() -
*
- * Called in tcop/postgres.c to tell the collector what the backend
+ * Called from tcop/postgres.c to tell the collector what the backend
* is actually doing (usually "" or the start of the query to
* be executed).
* --
@@ -988,49 +988,44 @@
/*
* Create or enlarge the pgStatTabstatMessages array
*/
-static bool
+static void
more_tabstat_space(void)
{
PgStat_MsgTabstat *newMessages;
PgStat_MsgTabstat **msgArray;
int newAlloc = pgStatTabstatAlloc + TABSTAT_QUANTUM;
int i;
+ MemoryContext oldCxt;
+ if (tabstatCxt == NULL)
+ tabstatCxt = AllocSetContextCreate(TopMemoryContext,
+ "per-backend statistics buffer",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+
+ oldCxt = MemoryContextSwitchTo(tabstatCxt);
+
/* Create (another) quantum of message buffers */
newMessages = (PgStat_MsgTabstat *)
- malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
- if (newMessages == NULL)
- {
- ereport(LOG,
-(errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
- return false;
- }
+ palloc0(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
/* Create or enlarge the pointer array */
if (pgStatTabstatMessages == NULL)
msgArray = (PgStat_MsgTabstat **)
- malloc(sizeof(PgStat_MsgTabstat *) * newAlloc);
+ palloc(sizeof(PgStat_MsgTabstat *) * newAlloc);
else
msgArray = (PgStat_MsgTabstat **)
- realloc(pgStatTabstatMessages,
- sizeof(PgStat_MsgTabstat *) * newAlloc);
- if (msgArray == NULL)
- {
- free(newMessages);
- ereport(LOG,
-(errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
- return false;
- }
+ repalloc(pgStatTabstatMessages,
+ sizeof(PgStat_MsgTabstat *) * newAlloc);
- MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[pgStatTabstatAlloc + i] = newMessages++;
pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = newAlloc;
- return true;
+ Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
+ MemoryContextSwitchTo(oldCxt);
}
/* --
@@ -1102,14 +1097,7 @@
* If we ran out of message buffers, we just allocate more.
*/
if (pgStatTabstatUsed >= pgStatTabstatAlloc)
- {
- if (!more_tabstat_space())
- {
- stats->no_stats = TRUE;
- return;
- }
- Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
- }
+ more_tabstat_space();
/*
* Use the first entry of the next message buffer.
@@ -1146,10 +1139,8 @@
* new xact-counters.
*/
if (pgStatTabstatAlloc == 0)
- {
- if (!more_tabstat_space())
- return;
- }
+ more_tabstat_space();
+
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
@@ -1180,10 +1178,8 @@
* new xact-counters.
*/
if (pgStatTabstatAlloc == 0)
- {
- if (!more_tabstat_space())
- return;
- }
+ more_tabstat_space();
+
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
@@ -1529,13 +1527,8 @@
/*
* Create the known backends table
*/
- pgStatBeTable = (PgStat_StatBeEntry *) malloc(
+ pgStatBeTable = (PgStat_StatBeEntry *) palloc0(
sizeof(PgStat_StatBeEntry) * MaxBackends);
- if (pgStatBeTable == NULL)
- ereport(ERROR,
-(errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory in statistics collector --- abort")));
- memset(pgStatBeTable, 0, sizeof(PgStat_StatBeEntry) * MaxBackends);
readPipe = pgStatPipe[0];
@@ -1804,11 +1799,7 @@
/*
* Allocate the message buffer
*/
- msgbuffer = (char *) malloc(PGSTAT_RECVBUFFERSZ);
- if (msgbuffer == NULL)
- ereport(ERROR,
-(errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory in statistics collector --- abort")));
+ msgbuffer = (char *) palloc(PGSTAT_RECVBUFFERSZ);
/*
* Loop forever
@@ -2416,7 +2412,7 @@
* simply return zero for anything and the collector simply starts
* from scratch with empty counters.
*/
- if ((fpin = fopen(pgStat_fname,