diff options
-rw-r--r-- | source3/configure.in | 2 | ||||
-rw-r--r-- | source3/include/smbprofile.h | 21 | ||||
-rw-r--r-- | source3/lib/util.c | 18 | ||||
-rw-r--r-- | source3/profile/profile.c | 21 | ||||
-rw-r--r-- | source3/tdb/spinlock.c | 17 |
5 files changed, 62 insertions, 17 deletions
diff --git a/source3/configure.in b/source3/configure.in index 40cf2d4a81..ca06afc08a 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2019,6 +2019,8 @@ if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday() is available]) fi +AC_LIBTESTFUNC(rt, clock_gettime) + AC_CACHE_CHECK([for va_copy],samba_cv_HAVE_VA_COPY,[ AC_TRY_LINK([#include <stdarg.h> va_list ap1,ap2;], [va_copy(ap1,ap2);], diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index dd171ac13e..fb5fa078c1 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -419,6 +419,25 @@ extern BOOL do_profile_times; #define DEC_PROFILE_COUNT(x) profile_p->x-- #define ADD_PROFILE_COUNT(x,y) profile_p->x += (y) +#if defined(HAVE_CLOCK_GETTIME) + +extern clockid_t __profile_clock; + +static inline unsigned long long profile_timestamp(void) +{ + struct timespec ts; + + /* FIXME: On a single-CPU system, or a system where we have bound + * daemon threads to single CPUs (eg. using cpusets or processor + * affinity), it might be preferable to use CLOCK_PROCESS_CPUTIME_ID. + */ + + clock_gettime(__profile_clock, &ts); + return (ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); /* usec */ +} + +#else + static inline unsigned long long profile_timestamp(void) { struct timeval tv; @@ -426,6 +445,8 @@ static inline unsigned long long profile_timestamp(void) return (tv.tv_sec * 1000000) + tv.tv_usec; } +#endif + /* end of helper macros */ #define DO_PROFILE_INC(x) \ diff --git a/source3/lib/util.c b/source3/lib/util.c index a9aebd0822..fd48cbfa83 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2969,3 +2969,21 @@ BOOL procid_is_local(const struct process_id *pid) { return True; } + +int this_is_smp(void) +{ +#if defined(HAVE_SYSCONF) + +#if defined(SYSCONF_SC_NPROC_ONLN) + return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; +#elif defined(SYSCONF_SC_NPROCESSORS_ONLN) + return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0; +#else + return 0; +#endif + +#else + return 0; +#endif +} + diff --git a/source3/profile/profile.c b/source3/profile/profile.c index db8a643042..bacf00eb01 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -28,6 +28,9 @@ #ifdef WITH_PROFILE static int shm_id; static BOOL read_only; +#if defined(HAVE_CLOCK_GETTIME) +clockid_t __profile_clock; +#endif #endif struct profile_header *profile_h; @@ -103,6 +106,24 @@ BOOL profile_setup(BOOL rdonly) 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; + } +#endif + again: /* try to use an existing key */ shm_id = shmget(PROF_SHMEM_KEY, 0, 0); diff --git a/source3/tdb/spinlock.c b/source3/tdb/spinlock.c index e6abb3a0bc..e42a6901c7 100644 --- a/source3/tdb/spinlock.c +++ b/source3/tdb/spinlock.c @@ -266,23 +266,6 @@ static void yield_cpu(void) #endif } -static int this_is_smp(void) -{ -#if defined(HAVE_SYSCONF) - -#if defined(SYSCONF_SC_NPROC_ONLN) - return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0; -#elif defined(SYSCONF_SC_NPROCESSORS_ONLN) - return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0; -#else - return 0; -#endif - -#else - return 0; -#endif -} - /* * GENERIC */ |