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 | |
| parent | b7eaff26dc71a4ecf54ab07674c9b4c4b0273544 (diff) | |
| download | samba-8882d08b6ba90c45f8107eef3d28614eb643dfb9.tar.gz samba-8882d08b6ba90c45f8107eef3d28614eb643dfb9.tar.bz2 samba-8882d08b6ba90c45f8107eef3d28614eb643dfb9.zip  | |
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')
| -rw-r--r-- | source3/aclocal.m4 | 42 | ||||
| -rw-r--r-- | source3/configure.in | 9 | ||||
| -rw-r--r-- | source3/profile/profile.c | 92 | 
3 files changed, 123 insertions, 20 deletions
diff --git a/source3/aclocal.m4 b/source3/aclocal.m4 index 8abecd216f..59bd26bd24 100644 --- a/source3/aclocal.m4 +++ b/source3/aclocal.m4 @@ -839,10 +839,17 @@ dnl Test whether the current LIBS results in libpthread being present.  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 @@ void main(void) {      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) +    ]) +]) diff --git a/source3/configure.in b/source3/configure.in index f8eba2349f..799441ed95 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2053,8 +2053,13 @@ if test x"$samba_cv_WITH_PROFILE" = x"yes"; then  	    [  		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 diff --git a/source3/profile/profile.c b/source3/profile/profile.c index ba9596301c..b0db629682 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:  | 
