From: Tom Lane Date: Sat, 2 Mar 2002 20:46:12 +0000 (+0000) Subject: Add code to allow profiling of backends on Linux: save and restore the X-Git-Tag: REL7_3~2003 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d8aa931ef5a3489764de222b1bfe43463d58a13;p=postgresql 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" --- diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 6bd43cae14..10519cc66c 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);