From 8d8aa931ef5a3489764de222b1bfe43463d58a13 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 2 Mar 2002 20:46:12 +0000
Subject: [PATCH] Add code to allow profiling of backends on Linux: save and
 restore the profiling timer setting across fork().  The correct way to build
 a profilable backend on Linux is now gmake PROFILE="-pg -DLINUX_PROFILE"

---
 src/backend/postmaster/postmaster.c | 47 +++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 6bd43cae144..10519cc66c3 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.267 2002/02/23 01:31:35 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.268 2002/03/02 20:46:12 tgl Exp $
  *
  * NOTES
  *
@@ -769,6 +769,14 @@ pmdaemonize(int argc, char *argv[])
 {
 	int			i;
 	pid_t		pid;
+#ifdef LINUX_PROFILE
+	struct itimerval prof_itimer;
+#endif
+
+#ifdef LINUX_PROFILE
+	/* see comments in BackendStartup */
+	getitimer(ITIMER_PROF, &prof_itimer);
+#endif
 
 	pid = fork();
 	if (pid == (pid_t) -1)
@@ -783,6 +791,10 @@ pmdaemonize(int argc, char *argv[])
 		_exit(0);
 	}
 
+#ifdef LINUX_PROFILE
+	setitimer(ITIMER_PROF, &prof_itimer, NULL);
+#endif
+
 	MyProcPid = getpid();		/* reset MyProcPid to child */
 
 /* GH: If there's no setsid(), we hopefully don't need silent mode.
@@ -1801,13 +1813,16 @@ SignalChildren(int signal)
 /*
  * BackendStartup -- start backend process
  *
- * returns: STATUS_ERROR if the fork/exec failed, STATUS_OK otherwise.
+ * returns: STATUS_ERROR if the fork failed, STATUS_OK otherwise.
  */
 static int
 BackendStartup(Port *port)
 {
 	Backend    *bn;				/* for backend cleanup */
 	pid_t		pid;
+#ifdef LINUX_PROFILE
+	struct itimerval prof_itimer;
+#endif
 
 	/*
 	 * Compute the cancel key that will be assigned to this backend. The
@@ -1838,6 +1853,16 @@ BackendStartup(Port *port)
 	fflush(stdout);
 	fflush(stderr);
 
+#ifdef LINUX_PROFILE
+	/*
+	 * Linux's fork() resets the profiling timer in the child process.
+	 * If we want to profile child processes then we need to save and restore
+	 * the timer setting.  This is a waste of time if not profiling, however,
+	 * so only do it if commanded by specific -DLINUX_PROFILE switch.
+	 */
+	getitimer(ITIMER_PROF, &prof_itimer);
+#endif
+
 #ifdef __BEOS__
 	/* Specific beos actions before backend startup */
 	beos_before_backend_startup();
@@ -1849,6 +1874,10 @@ BackendStartup(Port *port)
 	{
 		int			status;
 
+#ifdef LINUX_PROFILE
+		setitimer(ITIMER_PROF, &prof_itimer, NULL);
+#endif
+
 #ifdef __BEOS__
 		/* Specific beos backend startup actions */
 		beos_backend_startup();
@@ -2487,10 +2516,18 @@ SSDataBase(int xlop)
 {
 	pid_t		pid;
 	Backend    *bn;
+#ifdef LINUX_PROFILE
+	struct itimerval prof_itimer;
+#endif
 
 	fflush(stdout);
 	fflush(stderr);
 
+#ifdef LINUX_PROFILE
+	/* see comments in BackendStartup */
+	getitimer(ITIMER_PROF, &prof_itimer);
+#endif
+
 #ifdef __BEOS__
 	/* Specific beos actions before backend startup */
 	beos_before_backend_startup();
@@ -2505,6 +2542,10 @@ SSDataBase(int xlop)
 		char		dbbuf[ARGV_SIZE];
 		char		xlbuf[ARGV_SIZE];
 
+#ifdef LINUX_PROFILE
+		setitimer(ITIMER_PROF, &prof_itimer, NULL);
+#endif
+
 #ifdef __BEOS__
 		/* Specific beos actions after backend startup */
 		beos_backend_startup();
@@ -2603,7 +2644,7 @@ SSDataBase(int xlop)
 	 */
 	if (xlop == BS_XLOG_CHECKPOINT)
 	{
-		if (!(bn = (Backend *) calloc(1, sizeof(Backend))))
+		if (!(bn = (Backend *) malloc(sizeof(Backend))))
 		{
 			elog(DEBUG, "CheckPointDataBase: malloc failed");
 			ExitPostmaster(1);
-- 
GitLab