]> granicus.if.org Git - postgresql/commitdiff
Add code to allow profiling of backends on Linux: save and restore the
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 2 Mar 2002 20:46:12 +0000 (20:46 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 2 Mar 2002 20:46:12 +0000 (20:46 +0000)
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

index 6bd43cae144a3e8835ed8916a8b4ba8f11a10853..10519cc66c3b80684365233482559102dca111a4 100644 (file)
@@ -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);