The branch, master has been updated via 4c8531b s4/torture: use monotonic clock for time deltas in denytest via 6000260 s4/ldb: use monotonic clock for time deltas in ldbtest via 8aa0b70 s3: use monotonic time in timeout of sys_select_intr() via 73ad77f lib/util: add nsec_time_diff to calulate diffs from timespecs via 0ca6a73 s3: use monotonic clock for time deltas in namequery functions via 5728b0f s3: use monotonic clock for time deltas in smbtar via fc67675 s3: use monotonic clock for time deltas in smbclient via 6e9747c s3: add TspecDiff macro via 4b09919 s4:process_thread: use monotonic time for time deltas via c091b33 lib/util: add function to query the monotonic clock with the required fallback to the realtime clock via 63b1f2e libreplace: make a define for a best effort monotonic clock from 8c6ca6e s3: we have clock_gettime everywhere, remove ifdefs
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4c8531b642c579e69c27a8920c1aacbee04260c9 Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 18:58:20 2010 +0200 s4/torture: use monotonic clock for time deltas in denytest commit 60002600b86808551df0fb9b907869590b670450 Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 18:54:42 2010 +0200 s4/ldb: use monotonic clock for time deltas in ldbtest commit 8aa0b709d4924262c73c96d54bc0a28fa8b8aff0 Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 18:02:19 2010 +0200 s3: use monotonic time in timeout of sys_select_intr() commit 73ad77f20a136b74a4ae381c8b97acf248d3c8fe Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 17:56:37 2010 +0200 lib/util: add nsec_time_diff to calulate diffs from timespecs commit 0ca6a73d011abd20d8a9256f6dfe3517bd1a27ef Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 15:46:22 2010 +0200 s3: use monotonic clock for time deltas in namequery functions commit 5728b0fb5f59f856d2f20a5237dc31a1ca0c4afe Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 15:44:54 2010 +0200 s3: use monotonic clock for time deltas in smbtar commit fc6767502896dfcd74767deae4775b3177369598 Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 12:15:54 2010 +0200 s3: use monotonic clock for time deltas in smbclient commit 6e9747c1ce4806c0b81400f2627579e0bbf95207 Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 15:30:16 2010 +0200 s3: add TspecDiff macro commit 4b09919f70b171bc6e053bc3014ffc0e36bc1ff1 Author: Björn Jacke <b...@sernet.de> Date: Wed Aug 25 12:23:50 2010 +0200 s4:process_thread: use monotonic time for time deltas commit c091b3344badac6241b85c6cf2f7dacb0f06047c Author: Björn Jacke <b...@sernet.de> Date: Mon Aug 30 12:10:29 2010 +0200 lib/util: add function to query the monotonic clock with the required fallback to the realtime clock commit 63b1f2ee813b430e1f4bec3abb28a6266f8a82c8 Author: Björn Jacke <b...@sernet.de> Date: Thu Aug 26 12:22:02 2010 +0200 libreplace: make a define for a best effort monotonic clock ----------------------------------------------------------------------- Summary of changes: lib/replace/system/time.h | 7 +++++++ lib/util/time.c | 19 +++++++++++++++++++ lib/util/time.h | 10 ++++++++++ source3/client/client.c | 28 +++++++++++++--------------- source3/client/clitar.c | 14 +++++++------- source3/include/smb_macros.h | 9 +++++++++ source3/lib/select.c | 21 +++++++++++---------- source3/libsmb/namequery.c | 24 ++++++++++++------------ source4/lib/ldb/tools/ldbtest.c | 8 ++++---- source4/smbd/process_thread.c | 19 ++++++++++--------- source4/torture/basic/denytest.c | 30 +++++++++++++++--------------- 11 files changed, 117 insertions(+), 72 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/replace/system/time.h b/lib/replace/system/time.h index ff26531..3605d26 100644 --- a/lib/replace/system/time.h +++ b/lib/replace/system/time.h @@ -67,9 +67,16 @@ int rep_utimes(const char *filename, const struct timeval tv[2]); #endif #ifndef HAVE_CLOCK_GETTIME +/* CLOCK_REALTIME is required by POSIX */ #define CLOCK_REALTIME 0 typedef int clockid_t; int rep_clock_gettime(clockid_t clk_id, struct timespec *tp); #endif +/* make sure we have a best effort CUSTOM_CLOCK_MONOTONIC we can rely on */ +#ifndef CLOCK_MONOTONIC +#define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME +#else +#define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC +#endif #endif diff --git a/lib/util/time.c b/lib/util/time.c index 571219b..5ecf93c 100644 --- a/lib/util/time.c +++ b/lib/util/time.c @@ -55,6 +55,16 @@ _PUBLIC_ void GetTimeOfDay(struct timeval *tval) #endif } +/** +a wrapper to preferably get the monotonic time +**/ +_PUBLIC_ void clock_gettime_mono(struct timespec *tp) +{ + if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) != 0) { + clock_gettime(CLOCK_REALTIME,tp); + } +} + #define TIME_FIXUP_CONSTANT 11644473600LL @@ -399,6 +409,15 @@ _PUBLIC_ int64_t usec_time_diff(const struct timeval *tv1, const struct timeval return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec); } +/** + return (tp1 - tp2) in microseconds +*/ +_PUBLIC_ int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2) +{ + int64_t sec_diff = tp1->tv_sec - tp2->tv_sec; + return (sec_diff * 1000000000) + (int64_t)(tp1->tv_nsec - tp2->tv_nsec); +} + /** return a zero timeval diff --git a/lib/util/time.h b/lib/util/time.h index cf6dc1c..720a262 100644 --- a/lib/util/time.h +++ b/lib/util/time.h @@ -51,6 +51,11 @@ a gettimeofday wrapper _PUBLIC_ void GetTimeOfDay(struct timeval *tval); /** +a wrapper to preferably get the monotonic time +**/ +_PUBLIC_ void clock_gettime_mono(struct timespec *tp); + +/** interpret an 8 byte "filetime" structure to a time_t It's originally in "100ns units since jan 1st 1601" **/ @@ -144,6 +149,11 @@ _PUBLIC_ NTTIME nttime_from_string(const char *s); _PUBLIC_ int64_t usec_time_diff(const struct timeval *tv1, const struct timeval *tv2); /** + return (tp1 - tp2) in nanoseconds +*/ +_PUBLIC_ int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2); + +/** return a zero timeval */ _PUBLIC_ struct timeval timeval_zero(void); diff --git a/source3/client/client.c b/source3/client/client.c index 0ce4461..c911559 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1023,7 +1023,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget) int handle = 0; uint16_t fnum; bool newhandle = false; - struct timeval tp_start; + struct timespec tp_start; uint16 attr; SMB_OFF_T size; off_t start = 0; @@ -1048,7 +1048,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget) return 1; } - GetTimeOfDay(&tp_start); + clock_gettime_mono(&tp_start); status = cli_open(targetcli, targetname, O_RDONLY, DENY_NONE, &fnum); if (!NT_STATUS_IS_OK(status)) { @@ -1115,13 +1115,11 @@ static int do_get(const char *rname, const char *lname_in, bool reget) } { - struct timeval tp_end; + struct timespec tp_end; int this_time; - GetTimeOfDay(&tp_end); - this_time = - (tp_end.tv_sec - tp_start.tv_sec)*1000 + - (tp_end.tv_usec - tp_start.tv_usec)/1000; + clock_gettime_mono(&tp_end); + this_time = TspecDiff(&tp_start,&tp_end); get_total_time_ms += this_time; get_total_size += nread; @@ -1681,7 +1679,7 @@ static int do_put(const char *rname, const char *lname, bool reput) XFILE *f; SMB_OFF_T start = 0; int rc = 0; - struct timeval tp_start; + struct timespec tp_start; struct cli_state *targetcli; char *targetname = NULL; struct push_state state; @@ -1692,7 +1690,7 @@ static int do_put(const char *rname, const char *lname, bool reput) return 1; } - GetTimeOfDay(&tp_start); + clock_gettime_mono(&tp_start); if (reput) { status = cli_open(targetcli, targetname, O_RDWR|O_CREAT, DENY_NONE, &fnum); @@ -1766,13 +1764,11 @@ static int do_put(const char *rname, const char *lname, bool reput) } { - struct timeval tp_end; + struct timespec tp_end; int this_time; - GetTimeOfDay(&tp_end); - this_time = - (tp_end.tv_sec - tp_start.tv_sec)*1000 + - (tp_end.tv_usec - tp_start.tv_usec)/1000; + clock_gettime_mono(&tp_end); + this_time = TspecDiff(&tp_start,&tp_end); put_total_time_ms += this_time; put_total_size += state.nread; @@ -4508,9 +4504,11 @@ static void readline_callback(void) fd_set fds; struct timeval timeout; static time_t last_t; + struct timespec now; time_t t; - t = time(NULL); + clock_gettime_mono(&now); + t = now.tv_sec; if (t - last_t < 5) return; diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 16493ec..534b721 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -629,9 +629,9 @@ static void do_atar(const char *rname_in, char *lname, char *rname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - struct timeval tp_start; + struct timespec tp_start; - GetTimeOfDay(&tp_start); + clock_gettime_mono(&tp_start); data = SMB_MALLOC_ARRAY(char, read_size); if (!data) { @@ -768,15 +768,15 @@ static void do_atar(const char *rname_in, char *lname, fnum = -1; if (shallitime) { - struct timeval tp_end; + struct timespec tp_end; int this_time; /* if shallitime is true then we didn't skip */ if (tar_reset && !dry_run) (void) do_setrattr(finfo.name, aARCH, ATTRRESET); - GetTimeOfDay(&tp_end); - this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000; + clock_gettime_mono(&tp_end); + this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_nsec - tp_start.tv_nsec)/1000000; get_total_time_ms += this_time; get_total_size += finfo.size; @@ -1165,13 +1165,13 @@ static char *get_longfilename(file_info2 finfo) static void do_tarput(void) { file_info2 finfo; - struct timeval tp_start; + struct timespec tp_start; char *longfilename = NULL, linkflag; int skip = False; ZERO_STRUCT(finfo); - GetTimeOfDay(&tp_start); + clock_gettime_mono(&tp_start); DEBUG(5, ("RJS do_tarput called ...\n")); buffer_p = tarbuf + tbufsiz; /* init this to force first read */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 757c8a2..e72f2aa 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -153,6 +153,15 @@ values (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \ ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000) +/******************************************************************* +find the difference in milliseconds between two struct timespec +values +********************************************************************/ + +#define TspecDiff(tvalold,tvalnew) \ + (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \ + ((int)(tvalnew)->tv_nsec - (int)(tvalold)->tv_nsec)/1000000) + /**************************************************************************** true if two IPv4 addresses are equal ****************************************************************************/ diff --git a/source3/lib/select.c b/source3/lib/select.c index b5443ff..846e6af 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -148,17 +148,18 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf { int ret; fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf; - struct timeval tval2, *ptval, end_time; + struct timeval tval2, *ptval; + struct timespec end_time; readfds2 = (readfds ? &readfds_buf : NULL); writefds2 = (writefds ? &writefds_buf : NULL); errorfds2 = (errorfds ? &errorfds_buf : NULL); if (tval) { - GetTimeOfDay(&end_time); + clock_gettime_mono(&end_time); end_time.tv_sec += tval->tv_sec; - end_time.tv_usec += tval->tv_usec; - end_time.tv_sec += end_time.tv_usec / 1000000; - end_time.tv_usec %= 1000000; + end_time.tv_nsec += tval->tv_usec *1000; + end_time.tv_sec += end_time.tv_nsec / 1000000000; + end_time.tv_nsec %= 1000000000; errno = 0; tval2 = *tval; ptval = &tval2; @@ -174,17 +175,17 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf if (errorfds) errorfds_buf = *errorfds; if (ptval && (errno == EINTR)) { - struct timeval now_time; + struct timespec now_time; int64_t tdif; - GetTimeOfDay(&now_time); - tdif = usec_time_diff(&end_time, &now_time); + clock_gettime_mono(&now_time); + tdif = nsec_time_diff(&end_time,&now_time); if (tdif <= 0) { ret = 0; /* time expired. */ break; } - ptval->tv_sec = tdif / 1000000; - ptval->tv_usec = tdif % 1000000; + ptval->tv_sec = tdif / 1000000000; + ptval->tv_usec = (tdif % 1000000000) / 1000; } /* We must use select and not sys_select here. If we use diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c79480f..c949d3b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -261,7 +261,7 @@ NODE_STATUS_STRUCT *node_status_query(int fd, bool found=False; int retries = 2; int retry_time = 2000; - struct timeval tval; + struct timespec tp; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; @@ -297,7 +297,7 @@ NODE_STATUS_STRUCT *node_status_query(int fd, p.timestamp = time(NULL); p.packet_type = NMB_PACKET; - GetTimeOfDay(&tval); + clock_gettime_mono(&tp); if (!send_packet(&p)) return NULL; @@ -305,14 +305,14 @@ NODE_STATUS_STRUCT *node_status_query(int fd, retries--; while (1) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { + struct timespec tp2; + clock_gettime_mono(&tp2); + if (TspecDiff(&tp,&tp2) > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) return NULL; - GetTimeOfDay(&tval); + clock_gettime_mono(&tp); retries--; } @@ -655,7 +655,7 @@ struct sockaddr_storage *name_query(int fd, bool found=false; int i, retries = 3; int retry_time = bcast?250:2000; - struct timeval tval; + struct timespec tp; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; @@ -705,7 +705,7 @@ struct sockaddr_storage *name_query(int fd, p.timestamp = time(NULL); p.packet_type = NMB_PACKET; - GetTimeOfDay(&tval); + clock_gettime_mono(&tp); if (!send_packet(&p)) return NULL; @@ -713,15 +713,15 @@ struct sockaddr_storage *name_query(int fd, retries--; while (1) { - struct timeval tval2; + struct timespec tp2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { + clock_gettime_mono(&tp2); + if (TspecDiff(&tp,&tp2) > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) return NULL; - GetTimeOfDay(&tval); + clock_gettime_mono(&tp); retries--; } diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index b76889c..a885b80 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -40,19 +40,19 @@ #include "ldb.h" #include "tools/cmdline.h" -static struct timeval tp1,tp2; +static struct timespec tp1,tp2; static struct ldb_cmdline *options; static void _start_timer(void) { - gettimeofday(&tp1,NULL); + clock_gettime_mono(&tp1); } static double _end_timer(void) { - gettimeofday(&tp2,NULL); + clock_gettime_mono(&tp2); return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); + (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); } static void add_records(struct ldb_context *ldb, diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c index 8af785d..c047d23 100644 --- a/source4/smbd/process_thread.c +++ b/source4/smbd/process_thread.c @@ -233,17 +233,18 @@ static int thread_mutex_destroy(smb_mutex_t *mutex, const char *name) return pthread_mutex_destroy((pthread_mutex_t *)mutex->mutex); } -static void mutex_start_timer(struct timeval *tp1) +static void mutex_start_timer(struct timespec *tp1) { - gettimeofday(tp1,NULL); + clock_gettime_mono(tp1); } -static double mutex_end_timer(struct timeval tp1) +static double mutex_end_timer(struct timespec tp1) { - struct timeval tp2; - gettimeofday(&tp2,NULL); + struct timespec tp2; + + clock_gettime_mono(&tp2); return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); + (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); } /* @@ -254,7 +255,7 @@ static int thread_mutex_lock(smb_mutex_t *mutexP, const char *name) pthread_mutex_t *mutex = (pthread_mutex_t *)mutexP->mutex; int rc; double t; - struct timeval tp1; + struct timespec tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_mutex_trylock(mutex))) { if (rc == EBUSY) { @@ -316,7 +317,7 @@ static int thread_rwlock_lock_read(smb_rwlock_t *rwlockP, const char *name) pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock; int rc; double t; - struct timeval tp1; + struct time tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_rwlock_tryrdlock(rwlock))) { if (rc == EBUSY) { @@ -345,7 +346,7 @@ static int thread_rwlock_lock_write(smb_rwlock_t *rwlockP, const char *name) pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock; int rc; double t; - struct timeval tp1; + struct timespec tp1; /* Test below is ONLY for debugging */ if ((rc = pthread_rwlock_trywrlock(rwlock))) { if (rc == EBUSY) { diff --git a/source4/torture/basic/denytest.c b/source4/torture/basic/denytest.c index 174a1b2..7480c38 100644 --- a/source4/torture/basic/denytest.c +++ b/source4/torture/basic/denytest.c @@ -1416,7 +1416,7 @@ bool torture_denytest1(struct torture_context *tctx, int fnum1, fnum2; int i; bool correct = true; - struct timeval tv, tv_start; + struct timespec tv, tv_start; const char *fnames[2] = {"\\denytest1.dat", "\\denytest1.exe"}; int failures=0; @@ -1431,7 +1431,7 @@ bool torture_denytest1(struct torture_context *tctx, torture_comment(tctx, "Testing %d entries\n", (int)ARRAY_SIZE(denytable1)); - GetTimeOfDay(&tv_start); + clock_gettime_mono(&tv_start); for (i=0; i<ARRAY_SIZE(denytable1); i++) { enum deny_result res; @@ -1474,9 +1474,9 @@ bool torture_denytest1(struct torture_context *tctx, if (torture_setting_bool(tctx, "showall", false) || res != denytable1[i].result) { int64_t tdif; - GetTimeOfDay(&tv); - tdif = usec_time_diff(&tv, &tv_start); - tdif /= 1000; + clock_gettime_mono(&tv); + tdif = nsec_time_diff(&tv, &tv_start); + tdif /= 1000000; torture_comment(tctx, "%lld: %s %8s %10s %8s %10s %s (correct=%s)\n", (long long)tdif, fname, @@ -1518,7 +1518,7 @@ bool torture_denytest2(struct torture_context *tctx, int i; bool correct = true; const char *fnames[2] = {"\\denytest2.dat", "\\denytest2.exe"}; - struct timeval tv, tv_start; + struct timespec tv, tv_start; int failures=0; -- Samba Shared Repository