diff -ur valgrind-1.9.4/coregrind/vg_clientfuncs.c valgrind-1.9.4-e2/coregrind/vg_clientfuncs.c --- valgrind-1.9.4/coregrind/vg_clientfuncs.c Sun Oct 6 00:15:42 2002 +++ valgrind-1.9.4-e2/coregrind/vg_clientfuncs.c Sat Mar 15 09:33:35 2003 @@ -564,7 +564,7 @@ if (n_now != n_orig) break; nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 53 * 1000 * 1000; /* 53 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SUSPEND (53); /* 53 milliseconds */ /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ VG_(nanosleep)( &nanosleep_interval, NULL); diff -ur valgrind-1.9.4/coregrind/vg_errcontext.c valgrind-1.9.4-e2/coregrind/vg_errcontext.c --- valgrind-1.9.4/coregrind/vg_errcontext.c Thu Feb 6 10:15:36 2003 +++ valgrind-1.9.4-e2/coregrind/vg_errcontext.c Mon Mar 17 23:52:32 2003 @@ -54,6 +54,8 @@ /* forwards ... */ static Supp* is_suppressible_error ( Error* err ); +/* get current time */ +static void vg_report_time_stamp (void); /*------------------------------------------------------------*/ /*--- Helper fns ---*/ @@ -98,6 +100,8 @@ VG_(pp_ExeContext) ( err->where ); } + if (VG_(clo_time_stamp) == True) + vg_report_time_stamp (); if (printCount) VG_(message)(Vg_UserMsg, "Observed %d times:", err->count ); if (err->tid > 1) @@ -762,6 +766,19 @@ } #undef STREQ + +static void vg_report_time_stamp (void) +{ + vg_time_t t; + struct vg_tm tm; + + t = VG_(time) (NULL); + tm = *VG_(localtime) (&t); + + VG_(message)(Vg_UserMsg, "Time: %d/%02d/%02d %02d:%02d:%02d", + tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec ); +} /*--------------------------------------------------------------------*/ /*--- end vg_errcontext.c ---*/ diff -ur valgrind-1.9.4/coregrind/vg_include.h valgrind-1.9.4-e2/coregrind/vg_include.h --- valgrind-1.9.4/coregrind/vg_include.h Tue Feb 25 08:21:53 2003 +++ valgrind-1.9.4-e2/coregrind/vg_include.h Tue Mar 18 00:14:18 2003 @@ -246,7 +246,13 @@ extern Bool VG_(clo_run_libc_freeres); /* Use the basic-block chaining optimisation? Default: YES */ extern Bool VG_(clo_chain_bb); - +/* report time of errors */ +extern Bool VG_(clo_time_stamp); +/* use this for ms (default is 1000*1000) */ +extern long VG_(clo_time_slice); +#define SLEEP_DELAY(ms) ((ms) * VG_(clo_time_slice)) +#define SLEEP_SYSCALL(ms) ((ms) * VG_(clo_time_slice)) +#define SLEEP_SUSPEND(ms) ((ms) * VG_(clo_time_slice)) /* --------------------------------------------------------------------- Debugging and profiling stuff @@ -703,7 +709,7 @@ pthread_cond_timedwait should wake up. If == 0xFFFFFFFF, this means infinitely far in the future, viz, pthread_cond_wait. */ - UInt awaken_at; + ULong awaken_at_us; /* If VgTs_WaitJoiner, return value, as generated by joinees. */ void* joinee_retval; @@ -983,6 +989,7 @@ extern void VG_(start_rdtsc_calibration) ( void ); extern void VG_(end_rdtsc_calibration) ( void ); extern UInt VG_(read_millisecond_timer) ( void ); +extern ULong VG_(read_microsecond_timer) ( void ); extern Int VG_(fcntl) ( Int fd, Int cmd, Int arg ); extern Int VG_(select)( Int n, @@ -998,6 +1005,23 @@ /* --- Connecting over the network --- */ extern Int VG_(connect_via_socket)( UChar* str ); + +typedef Int vg_time_t; + +struct vg_tm { + int tm_sec; /* Seconds. [0-60] (1 leap second) */ + int tm_min; /* Minutes. [0-59] */ + int tm_hour; /* Hours. [0-23] */ + int tm_mday; /* Day. [1-31] */ + int tm_mon; /* Month. [0-11] */ + int tm_year; /* Year - 1900. */ + int tm_wday; /* Day of week. [0-6] */ + int tm_yday; /* Days in year.[0-365] */ + int tm_isdst; /* DST. [-1/0/1]*/ +}; + +extern vg_time_t VG_(time) (vg_time_t *timep); +extern struct vg_tm * VG_(localtime) (vg_time_t *timep); /* --------------------------------------------------------------------- Exports of vg_message.c Only in valgrind-1.9.4-e2/coregrind: vg_include.h.orig diff -ur valgrind-1.9.4/coregrind/vg_libpthread.c valgrind-1.9.4-e2/coregrind/vg_libpthread.c --- valgrind-1.9.4/coregrind/vg_libpthread.c Sun Feb 23 14:49:39 2003 +++ valgrind-1.9.4-e2/coregrind/vg_libpthread.c Sat Mar 15 13:11:14 2003 @@ -1,4 +1,4 @@ - +#define YIELD_FOR_SLEEP 0 /*--------------------------------------------------------------------*/ /*--- A replacement for the standard libpthread.so. ---*/ /*--- vg_libpthread.c ---*/ @@ -1330,12 +1330,16 @@ my_assert(n_now >= n_orig); if (n_now != n_orig) break; +#if YIELD_FOR_SLEEP + pthread_yield (); +#else nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 12 * 1000 * 1000; /* 12 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (12); /* 12 milliseconds */ /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ (void)my_do_syscall2(__NR_nanosleep, (int)(&nanosleep_interval), (int)NULL); +#endif } * (__errno_location()) = EINTR; @@ -1913,12 +1917,16 @@ (stat(pathname, &st) == 0 && S_ISFIFO(st.st_mode))) { /* OK, we're opening a FIFO for writing; sleep and spin */ +#if YIELD_FOR_SLEEP + pthread_yield (); +#else nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 13 * 1000 * 1000; /* 13 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (13); /* 13 milliseconds */ /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ (void)my_do_syscall2(__NR_nanosleep, (int)(&nanosleep_interval), (int)NULL); +#endif } else { /* it was just an error */ errno = saved_errno; @@ -1969,12 +1977,16 @@ } /* Still nobody home; sleep and spin */ +#if YIELD_FOR_SLEEP + pthread_yield (); +#else nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 13 * 1000 * 1000; /* 13 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (13); /* 13 milliseconds */ /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ (void)my_do_syscall2(__NR_nanosleep, (int)(&nanosleep_interval), (int)NULL); +#endif } errno = saved_errno; @@ -2555,8 +2567,14 @@ /* fprintf(stderr, "MY_SELECT: nanosleep\n"); */ /* nanosleep and go round again */ +#if YIELD_FOR_SLEEP + pthread_yield (); + nanosleep_interval.tv_sec = 0; + nanosleep_interval.tv_nsec = 0; +#else nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 11 * 1000 * 1000; /* 11 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (11); /* 11 milliseconds */ +#endif /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ res = my_do_syscall2(__NR_nanosleep, @@ -2664,8 +2682,14 @@ /* fprintf(stderr, "MY_POLL: nanosleep\n"); */ /* nanosleep and go round again */ +#if YIELD_FOR_SLEEP + pthread_yield (); + nanosleep_interval.tv_sec = 0; + nanosleep_interval.tv_nsec = 0; +#else nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 13 * 1000 * 1000; /* 13 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (13); /* 13 milliseconds */ +#endif /* It's critical here that valgrind's nanosleep implementation is nonblocking. */ res = my_do_syscall2(__NR_nanosleep, @@ -3320,7 +3344,7 @@ ensure_valgrind("msgsnd"); nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 13 * 1000 * 1000; /* 13 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (13); /* 13 milliseconds */ if (msgflg & IPC_NOWAIT) { /* If we aren't blocking anyway, just do it */ @@ -3333,8 +3357,12 @@ if (err != -EAGAIN) break; +#if YIELD_FOR_SLEEP + pthread_yield (); +#else (void)my_do_syscall2(__NR_nanosleep, (int)(&nanosleep_interval), (int)NULL); +#endif } } @@ -3356,7 +3384,7 @@ ensure_valgrind("msgrcv"); nanosleep_interval.tv_sec = 0; - nanosleep_interval.tv_nsec = 13 * 1000 * 1000; /* 13 milliseconds */ + nanosleep_interval.tv_nsec = SLEEP_SYSCALL (13); /* 13 milliseconds */ tmp.msgp = msgp; tmp.msgtyp = msgtyp; @@ -3372,8 +3400,12 @@ if (err != -ENOMSG) break; +#if YIELD_FOR_SLEEP + pthread_yield (); +#else (void)my_do_syscall2(__NR_nanosleep, (int)(&nanosleep_interval), (int)NULL); +#endif } } diff -ur valgrind-1.9.4/coregrind/vg_main.c valgrind-1.9.4-e2/coregrind/vg_main.c --- valgrind-1.9.4/coregrind/vg_main.c Tue Feb 25 08:21:54 2003 +++ valgrind-1.9.4-e2/coregrind/vg_main.c Sat Mar 15 00:05:56 2003 @@ -487,6 +487,8 @@ Char* VG_(clo_weird_hacks) = NULL; Bool VG_(clo_run_libc_freeres) = True; Bool VG_(clo_chain_bb) = True; +Bool VG_(clo_time_stamp) = False; +long VG_(clo_time_slice) = 1000000L; /* This Bool is needed by wrappers in vg_clientmalloc.c to decide how @@ -567,6 +569,8 @@ " suppressions file \n" " --weird-hacks=hack1,hack2,... [no hacks selected]\n" " recognised hacks are: ioctl-VTIME truncate-writes lax-ioctls\n" +" --time-stamp=no|yes timestamp error reports? [no]\n" +" --time-slice= time slice factor [1000000]\n" "\n" " %s skin user options:\n"; @@ -973,6 +977,13 @@ if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE) VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE; } + + else if (STREQ(argv[i], "--time-stamp=yes")) + VG_(clo_time_stamp) = True; + else if (STREQ(argv[i], "--time-stamp=no")) + VG_(clo_time_stamp) = False; + else if (STREQN(13, argv[i], "--time-slice=")) + VG_(clo_time_slice) = (long)VG_(atoll)(&argv[i][13]); else if (VG_(needs).command_line_options) { Bool ok = SK_(process_cmd_line_option)(argv[i]); diff -ur valgrind-1.9.4/coregrind/vg_mylibc.c valgrind-1.9.4-e2/coregrind/vg_mylibc.c --- valgrind-1.9.4/coregrind/vg_mylibc.c Tue Feb 25 08:53:48 2003 +++ valgrind-1.9.4-e2/coregrind/vg_mylibc.c Tue Mar 18 00:07:07 2003 @@ -1295,6 +1295,18 @@ } +ULong VG_(read_microsecond_timer) ( void ) +{ + ULong rdtsc_now; + vg_assert(rdtsc_calibration_state == 2); + rdtsc_now = do_rdtsc_insn(); + vg_assert(rdtsc_now > rdtsc_cal_end_raw); + rdtsc_now -= rdtsc_cal_end_raw; + rdtsc_now = rdtsc_now/(rdtsc_ticks_per_millisecond/1000); + return rdtsc_now; +} + + void VG_(start_rdtsc_calibration) ( void ) { Int res; @@ -1652,6 +1664,121 @@ return res; } +/* this one is taken from linux kernel: arch/ppc64/kernel/time.c +*/ + +#define FEBRUARY 2 +#define STARTOFTIME 1970 +#define SECDAY 86400L +#define SECYR (SECDAY * 365) +#define leapyear(year) ((year) % 4 == 0) +#define days_in_year(a) (leapyear(a) ? 366 : 365) +#define days_in_month(a) (month_days[(a) - 1]) + +static int month_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +/* + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) + */ +static void +GregorianDay (struct vg_tm *tm) +{ + int leapsToDate; + int lastYear; + int day; + static int MonthOffset[] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + lastYear=tm->tm_year-1; + + /* + * Number of leap corrections to apply up to end of last year + */ + leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; + + /* + * This year is a leap year if it is divisible by 4 except when it is + * divisible by 100 unless it is divisible by 400 + * + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be + */ + if((tm->tm_year%4==0) && + ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && + (tm->tm_mon>2)) { + /* + * We are past Feb. 29 in a leap year + */ + day=1; + } else { + day=0; + } + + day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + + tm->tm_mday; + + tm->tm_wday=day%7; +} + +vg_time_t VG_(time) (vg_time_t *timep) +{ + Int res; + struct vki_timeval t_now; + vg_time_t t; + + res = vg_do_syscall2(__NR_gettimeofday, (int)&t_now, (int)NULL); + vg_assert(res == 0); + t = (vg_time_t)t_now.tv_sec; + + if (NULL != timep) + *timep = t; + return (t); +} + +struct vg_tm * VG_(localtime) (vg_time_t *timep) +{ + Int tim; + Int i; + Long hms, day; + struct vg_tm tm[1]; + + tim = (Int)*timep; + + day = tim / SECDAY; + hms = tim % SECDAY; + + /* Hours, minutes, seconds are easy */ + tm->tm_hour = hms / 3600; + tm->tm_min = (hms % 3600) / 60; + tm->tm_sec = (hms % 3600) % 60; + + /* Number of years in days */ + for (i = STARTOFTIME; day >= days_in_year(i); i++) + day -= days_in_year(i); + tm->tm_year = i; + + /* Number of months in days left */ + if (leapyear(tm->tm_year)) + days_in_month(FEBRUARY) = 29; + for (i = 1; day >= days_in_month(i); i++) + day -= days_in_month(i); + days_in_month(FEBRUARY) = 28; + tm->tm_mon = i; + + /* Days are what is left over (+1) from all that. */ + tm->tm_mday = day + 1; + + /* + * Determine the day of week + */ + GregorianDay(tm); + + vg_assert (tm->tm_year >= 1900); + tm->tm_year -= 1900; + + return (tm); +} /*--------------------------------------------------------------------*/ /*--- end vg_mylibc.c ---*/ diff -ur valgrind-1.9.4/coregrind/vg_scheduler.c valgrind-1.9.4-e2/coregrind/vg_scheduler.c --- valgrind-1.9.4/coregrind/vg_scheduler.c Sun Feb 23 14:32:15 2003 +++ valgrind-1.9.4-e2/coregrind/vg_scheduler.c Mon Mar 17 10:13:58 2003 @@ -29,6 +29,8 @@ */ #include "vg_include.h" +#define NO_TIMEOUT 0xFFFFFFFFFFFFFFFFULL + #include "valgrind.h" /* for VG_USERREQ__RUNNING_ON_VALGRIND and VG_USERREQ__DISCARD_TRANSLATIONS */ @@ -39,7 +41,7 @@ should I also save and restore: ThreadStatus.joiner ThreadStatus.waited_on_mid - ThreadStatus.awaken_at + ThreadStatus.awaken_at_us ThreadStatus.retval Currently unsure, and so am not doing so. @@ -597,7 +599,7 @@ VG_(threads)[tid].status = VgTs_Empty; VG_(threads)[tid].associated_mx = NULL; VG_(threads)[tid].associated_cv = NULL; - VG_(threads)[tid].awaken_at = 0; + VG_(threads)[tid].awaken_at_us = 0; VG_(threads)[tid].joinee_retval = NULL; VG_(threads)[tid].joiner_thread_return = NULL; VG_(threads)[tid].joiner_jee_tid = VG_INVALID_THREADID; @@ -814,18 +816,18 @@ syscall_no = VG_(threads)[tid].m_eax; /* syscall number */ if (syscall_no == __NR_nanosleep) { - UInt t_now, t_awaken; + ULong t_now, t_awaken; struct vki_timespec* req; req = (struct vki_timespec*)VG_(threads)[tid].m_ebx; /* arg1 */ - t_now = VG_(read_millisecond_timer)(); + t_now = VG_(read_microsecond_timer)(); t_awaken = t_now - + (UInt)1000ULL * (UInt)(req->tv_sec) - + (UInt)(req->tv_nsec) / 1000000; + + 1000000ULL * req->tv_sec + + req->tv_nsec / 1000; VG_(threads)[tid].status = VgTs_Sleeping; - VG_(threads)[tid].awaken_at = t_awaken; + VG_(threads)[tid].awaken_at_us = t_awaken; if (VG_(clo_trace_sched)) { - VG_(sprintf)(msg_buf, "at %d: nanosleep for %d", + VG_(sprintf)(msg_buf, "at %llu: nanosleep for %lld", t_now, t_awaken-t_now); print_sched_event(tid, msg_buf); } @@ -946,20 +948,20 @@ Char msg_buf[100]; struct vki_timespec* rem; - UInt t_now; + ULong t_now; /* Awaken any sleeping threads whose sleep has expired. */ for (tid = 1; tid < VG_N_THREADS; tid++) if (VG_(threads)[tid].status == VgTs_Sleeping) break; - /* Avoid pointless calls to VG_(read_millisecond_timer). */ + /* Avoid pointless calls to VG_(read_microsecond_timer). */ if (tid < VG_N_THREADS) { - t_now = VG_(read_millisecond_timer)(); + t_now = VG_(read_microsecond_timer)(); for (tid = 1; tid < VG_N_THREADS; tid++) { if (VG_(threads)[tid].status != VgTs_Sleeping) continue; - if (t_now >= VG_(threads)[tid].awaken_at) { + if (t_now >= VG_(threads)[tid].awaken_at_us) { /* Resume this thread. Set to zero the remaining-time (second) arg of nanosleep, since it's used up all its time. */ @@ -974,7 +976,7 @@ /* Reschedule this thread. */ VG_(threads)[tid].status = VgTs_Runnable; if (VG_(clo_trace_sched)) { - VG_(sprintf)(msg_buf, "at %d: nanosleep done", + VG_(sprintf)(msg_buf, "at %llu: nanosleep done", t_now); print_sched_event(tid, msg_buf); } @@ -1160,14 +1162,15 @@ static void check_for_pthread_cond_timedwait ( void ) { - Int i, now; + Int i; + ULong now; for (i = 1; i < VG_N_THREADS; i++) { if (VG_(threads)[i].status != VgTs_WaitCV) continue; - if (VG_(threads)[i].awaken_at == 0xFFFFFFFF /* no timeout */) + if (VG_(threads)[i].awaken_at_us == NO_TIMEOUT /* no timeout */) continue; - now = VG_(read_millisecond_timer)(); - if (now >= VG_(threads)[i].awaken_at) { + now = VG_(read_microsecond_timer)(); + if (now >= VG_(threads)[i].awaken_at_us) { do_pthread_cond_timedwait_TIMEOUT(i); } } @@ -1181,7 +1184,7 @@ struct vki_timespec req; struct vki_timespec rem; req.tv_sec = 0; - req.tv_nsec = 10 * 1000 * 1000; + req.tv_nsec = SLEEP_DELAY (10); res = VG_(nanosleep)( &req, &rem ); vg_assert(res == 0 /* ok */ || res == 1 /* interrupted by signal */); } @@ -1270,7 +1273,7 @@ || VG_(threads)[tid_next].status == VgTs_Sleeping || VG_(threads)[tid_next].status == VgTs_WaitSIG || (VG_(threads)[tid_next].status == VgTs_WaitCV - && VG_(threads)[tid_next].awaken_at != 0xFFFFFFFF)) + && VG_(threads)[tid_next].awaken_at_us != NO_TIMEOUT)) n_in_bounded_wait ++; if (VG_(threads)[tid_next].status == VgTs_Runnable) break; /* We can run this one. */ @@ -2575,7 +2578,7 @@ vg_assert(VG_(is_valid_tid)(tid) && VG_(threads)[tid].status == VgTs_WaitCV - && VG_(threads)[tid].awaken_at != 0xFFFFFFFF); + && VG_(threads)[tid].awaken_at_us != NO_TIMEOUT); mx = VG_(threads)[tid].associated_mx; vg_assert(mx != NULL); cv = VG_(threads)[tid].associated_cv; @@ -2699,7 +2702,7 @@ { Char msg_buf[100]; - /* If ms_end == 0xFFFFFFFF, wait forever (no timeout). Otherwise, + /* If ms_end == 0xFFFFFFFF, wait forever (no timeout). Otherwise, ms_end is the ending millisecond. */ /* pre: mutex should be a valid mutex and owned by tid. */ @@ -2754,7 +2757,8 @@ VG_(threads)[tid].status = VgTs_WaitCV; VG_(threads)[tid].associated_cv = cond; VG_(threads)[tid].associated_mx = mutex; - VG_(threads)[tid].awaken_at = ms_end; + VG_(threads)[tid].awaken_at_us = ms_end == 0xFFFFFFFF + ? NO_TIMEOUT : (ULong)ms_end*1000; if (VG_(clo_trace_pthread_level) >= 1) { VG_(sprintf)(msg_buf,