Author: jpeach Date: 2006-06-09 01:02:54 +0000 (Fri, 09 Jun 2006) New Revision: 16111
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16111 Log: Patch from Bj?\195?\182rn JACKE <[EMAIL PROTECTED]>. 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. Modified: branches/SAMBA_3_0/source/aclocal.m4 branches/SAMBA_3_0/source/configure.in branches/SAMBA_3_0/source/profile/profile.c trunk/source/aclocal.m4 trunk/source/configure.in trunk/source/profile/profile.c Changeset: Modified: branches/SAMBA_3_0/source/aclocal.m4 =================================================================== --- branches/SAMBA_3_0/source/aclocal.m4 2006-06-09 00:04:36 UTC (rev 16110) +++ branches/SAMBA_3_0/source/aclocal.m4 2006-06-09 01:02:54 UTC (rev 16111) @@ -839,10 +839,17 @@ dnl Execute the corresponding user action list. AC_DEFUN([SMB_IS_LIBPTHREAD_LINKED], [ + AC_MSG_CHECKING(if libpthread is linked) AC_TRY_LINK([], [return pthread_create(0, 0, 0, 0);], - [$1], - [$2]) + [ + AC_MSG_RESULT(yes) + $1 + ], + [ + AC_MSG_RESULT(no) + $2 + ]) ]) dnl SMB_REMOVE_LIB(lib) @@ -943,3 +950,34 @@ fi ]) + +dnl SMB_CHECK_CLOCK_ID(clockid) +dnl Test whether the specified clock_gettime clock ID is available. If it +dnl is, we define HAVE_clockid +AC_DEFUN([SMB_CHECK_CLOCK_ID], +[ + AC_MSG_CHECKING(for $1) + AC_TRY_LINK([ +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + ], + [ +clockid_t clk = $1; + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_$1, 1, + [Whether the clock_gettime clock ID $1 is available]) + ], + [ + AC_MSG_RESULT(no) + ]) +]) Modified: branches/SAMBA_3_0/source/configure.in =================================================================== --- branches/SAMBA_3_0/source/configure.in 2006-06-09 00:04:36 UTC (rev 16110) +++ branches/SAMBA_3_0/source/configure.in 2006-06-09 01:02:54 UTC (rev 16111) @@ -2053,8 +2053,13 @@ [ SMB_IS_LIBPTHREAD_LINKED( [ SMB_REMOVELIB(rt) ], - [ AC_DEFINE(HAVE_CLOCK_GETTIME, 1, - [Whether clock_gettime is available]) ]) + [ + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, + [Whether clock_gettime is available]) + SMB_CHECK_CLOCK_ID(CLOCK_MONOTONIC) + SMB_CHECK_CLOCK_ID(CLOCK_PROCESS_CPUTIME_ID) + SMB_CHECK_CLOCK_ID(CLOCK_REALTIME) + ]) ]) fi Modified: branches/SAMBA_3_0/source/profile/profile.c =================================================================== --- branches/SAMBA_3_0/source/profile/profile.c 2006-06-09 00:04:36 UTC (rev 16110) +++ branches/SAMBA_3_0/source/profile/profile.c 2006-06-09 01:02:54 UTC (rev 16111) @@ -30,6 +30,7 @@ static BOOL read_only; #if defined(HAVE_CLOCK_GETTIME) clockid_t __profile_clock; +BOOL have_profiling_clock = False; #endif #endif @@ -62,6 +63,19 @@ (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 @@ 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: Modified: trunk/source/aclocal.m4 =================================================================== --- trunk/source/aclocal.m4 2006-06-09 00:04:36 UTC (rev 16110) +++ trunk/source/aclocal.m4 2006-06-09 01:02:54 UTC (rev 16111) @@ -839,10 +839,17 @@ dnl Execute the corresponding user action list. AC_DEFUN([SMB_IS_LIBPTHREAD_LINKED], [ + AC_MSG_CHECKING(if libpthread is linked) AC_TRY_LINK([], [return pthread_create(0, 0, 0, 0);], - [$1], - [$2]) + [ + AC_MSG_RESULT(yes) + $1 + ], + [ + AC_MSG_RESULT(no) + $2 + ]) ]) dnl SMB_REMOVE_LIB(lib) @@ -943,3 +950,34 @@ fi ]) + +dnl SMB_CHECK_CLOCK_ID(clockid) +dnl Test whether the specified clock_gettime clock ID is available. If it +dnl is, we define HAVE_clockid +AC_DEFUN([SMB_CHECK_CLOCK_ID], +[ + AC_MSG_CHECKING(for $1) + AC_TRY_LINK([ +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + ], + [ +clockid_t clk = $1; + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_$1, 1, + [Whether the clock_gettime clock ID $1 is available]) + ], + [ + AC_MSG_RESULT(no) + ]) +]) Modified: trunk/source/configure.in =================================================================== --- trunk/source/configure.in 2006-06-09 00:04:36 UTC (rev 16110) +++ trunk/source/configure.in 2006-06-09 01:02:54 UTC (rev 16111) @@ -2056,8 +2056,13 @@ [ SMB_IS_LIBPTHREAD_LINKED( [ SMB_REMOVELIB(rt) ], - [ AC_DEFINE(HAVE_CLOCK_GETTIME, 1, - [Whether clock_gettime is available]) ]) + [ + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, + [Whether clock_gettime is available]) + SMB_CHECK_CLOCK_ID(CLOCK_MONOTONIC) + SMB_CHECK_CLOCK_ID(CLOCK_PROCESS_CPUTIME_ID) + SMB_CHECK_CLOCK_ID(CLOCK_REALTIME) + ]) ]) fi Modified: trunk/source/profile/profile.c =================================================================== --- trunk/source/profile/profile.c 2006-06-09 00:04:36 UTC (rev 16110) +++ trunk/source/profile/profile.c 2006-06-09 01:02:54 UTC (rev 16111) @@ -30,6 +30,7 @@ static BOOL read_only; #if defined(HAVE_CLOCK_GETTIME) clockid_t __profile_clock; +BOOL have_profiling_clock = False; #endif #endif @@ -62,6 +63,19 @@ (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 @@ 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:
