diff options
author | James Peach <jpeach@samba.org> | 2006-06-09 01:02:54 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:17:20 -0500 |
commit | 8882d08b6ba90c45f8107eef3d28614eb643dfb9 (patch) | |
tree | 132d98a983eb0cffb53cbc6adc5c3cfcbfb05366 /source3/profile | |
parent | b7eaff26dc71a4ecf54ab07674c9b4c4b0273544 (diff) | |
download | samba-8882d08b6ba90c45f8107eef3d28614eb643dfb9.tar.gz |
r16111: Patch from Björn JACKE <samba@j3e.de>.
This fixes a problem where the clock definition for clock_gettime() is
present at compile time, but is not available on the running system. In
this case, we fall back to less-preferred clocks until we find one that
we can use.
(This used to be commit fc6ed6a1aa2225ccde04c4ecaf0777dc0de4f1cb)
Diffstat (limited to 'source3/profile')
-rw-r--r-- | source3/profile/profile.c | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/source3/profile/profile.c b/source3/profile/profile.c index ba9596301c6..b0db6296829 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -30,6 +30,7 @@ static int shm_id; static BOOL read_only; #if defined(HAVE_CLOCK_GETTIME) clockid_t __profile_clock; +BOOL have_profiling_clock = False; #endif #endif @@ -62,6 +63,19 @@ void profile_message(int msg_type, struct process_id src, void *buf, size_t len) (int)procid_to_pid(&src))); break; case 2: /* turn on complete profiling */ + +#if defined(HAVE_CLOCK_GETTIME) + if (!have_profiling_clock) { + do_profile_flag = True; + do_profile_times = False; + DEBUG(1,("INFO: Profiling counts turned ON from " + "pid %d\n", (int)procid_to_pid(&src))); + DEBUGADD(1,("INFO: Profiling times disabled " + "due to lack of a suitable clock\n")); + break; + } +#endif + do_profile_flag = True; do_profile_times = True; DEBUG(1,("INFO: Full profiling turned ON from pid %d\n", @@ -100,28 +114,74 @@ void reqprofile_message(int msg_type, struct process_id src, open the profiling shared memory area ******************************************************************/ #ifdef WITH_PROFILE + +#ifdef HAVE_CLOCK_GETTIME + +/* Find a clock. Just because the definition for a particular clock ID is + * present doesn't mean the system actually supports it. + */ +static void init_clock_gettime(void) +{ + struct timespec ts; + + have_profiling_clock = False; + +#ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID + /* CLOCK_PROCESS_CPUTIME_ID is sufficiently fast that the + * always profiling times is plausible. Unfortunately on Linux + * it is only accurate if we can guarantee we will not be scheduled + * scheduled onto a different CPU between samples. Until there is + * some way to set processor affinity, we can only use this on + * uniprocessors. + */ + if (!this_is_smp()) { + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) { + DEBUG(10, ("Using CLOCK_PROCESS_CPUTIME_ID " + "for profile_clock\n")); + __profile_clock = CLOCK_PROCESS_CPUTIME_ID; + have_profiling_clock = True; + } + } +#endif + +#ifdef HAVE_CLOCK_MONOTONIC + if (!have_profiling_clock && + clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + DEBUG(10, ("Using CLOCK_MONOTONIC for profile_clock\n")); + __profile_clock = CLOCK_MONOTONIC; + have_profiling_clock = True; + return; + } +#endif + +#ifdef HAVE_CLOCK_REALTIME + /* POSIX says that CLOCK_REALTIME should be defined everywhere + * where we have clock_gettime... + */ + if (!have_profiling_clock && + clock_gettime(CLOCK_REALTIME, &ts) == 0) { + __profile_clock = CLOCK_REALTIME; + have_profiling_clock = True; + } + + SMB_WARN(__profile_clock == CLOCK_REALTIME, + ("Using (slow) CLOCK_REALTIME for profile_clock")); +#endif + + SMB_WARN(have_profiling_clock == False, + ("could not find a working clock for profiling")); + return have_profiling_clock; +} +#endif + BOOL profile_setup(BOOL rdonly) { struct shmid_ds shm_ds; read_only = rdonly; -#if defined(HAVE_CLOCK_GETTIME) - if (this_is_smp()) { - /* This is faster that gettimeofday, but not fast enough to - * leave it enabled in production. - */ - __profile_clock = CLOCK_MONOTONIC; - } else { - /* CLOCK_PROCESS_CPUTIME_ID is sufficiently fast that the - * always profiling times is plausible. Unfortunately it is - * only accurate if we can guarantee we will not be scheduled - * onto a different CPU between samples. Until there is some - * way to set processor affinity, we can only use this on - * uniprocessors. - */ - __profile_clock = CLOCK_PROCESS_CPUTIME_ID; - } +#ifdef HAVE_CLOCK_GETTIME + init_clock_gettime(); #endif again: |