Delay functions don't necessarily end right at the exact time asked. Change udelay and ndelay to return the last read time in microseconds and nanoseconds, respectively. A side effect is that udelay(0) and ndelay(0) return approximate current time.
Add an nsec() call to return the current nanoseconds as a uint64_t. While we're at it, have timing.c including timing.h so we can be sure the prototypes match the function definitions. And, finally, clang-format it. Change-Id: I22b855ac055314a1846dc45f93378675104f13a4 Signed-off-by: Ronald G. Minnich <[email protected]> --- user/parlib/include/parlib/timing.h | 5 +++-- user/parlib/timing.c | 31 +++++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/user/parlib/include/parlib/timing.h b/user/parlib/include/parlib/timing.h index 86833a6..eb15a8a 100644 --- a/user/parlib/include/parlib/timing.h +++ b/user/parlib/include/parlib/timing.h @@ -5,8 +5,8 @@ __BEGIN_DECLS -void udelay(uint64_t usec); -void ndelay(uint64_t nsec); +uint64_t udelay(uint64_t usec); +uint64_t ndelay(uint64_t nsec); uint64_t udiff(uint64_t begin, uint64_t end); uint64_t ndiff(uint64_t begin, uint64_t end); @@ -19,5 +19,6 @@ uint64_t sec2tsc(uint64_t sec); uint64_t msec2tsc(uint64_t msec); uint64_t usec2tsc(uint64_t usec); uint64_t nsec2tsc(uint64_t nsec); +uint64_t nsec(void); __END_DECLS diff --git a/user/parlib/timing.c b/user/parlib/timing.c index 983d862..7d32997 100644 --- a/user/parlib/timing.c +++ b/user/parlib/timing.c @@ -1,44 +1,46 @@ +#include <parlib/arch/arch.h> #include <parlib/common.h> +#include <parlib/timing.h> #include <ros/procinfo.h> -#include <parlib/arch/arch.h> #include <stdio.h> -#include <parlib/tsc-compat.h> -void udelay(uint64_t usec) +uint64_t udelay(uint64_t usec) { uint64_t start, end, now; start = read_tsc(); - end = start + (get_tsc_freq() * usec) / 1000000; + end = start + (get_tsc_freq() * usec) / 1000000; do { - cpu_relax(); - now = read_tsc(); + cpu_relax(); + now = read_tsc(); } while (now < end || (now > start && end < start)); + return tsc2usec(now); } /* Not super accurate, due to overheads of reading tsc and looping */ -void ndelay(uint64_t nsec) +uint64_t ndelay(uint64_t nsec) { uint64_t start, end, now; start = read_tsc(); - end = start + (get_tsc_freq() * nsec) / 1000000000; + end = start + (get_tsc_freq() * nsec) / 1000000000; do { - cpu_relax(); - now = read_tsc(); + cpu_relax(); + now = read_tsc(); } while (now < end || (now > start && end < start)); + return tsc2nsec(now); } /* Difference between the ticks in microseconds */ uint64_t udiff(uint64_t begin, uint64_t end) { - return (end - begin) * 1000000 / __procinfo.tsc_freq; + return (end - begin) * 1000000 / __procinfo.tsc_freq; } /* Difference between the ticks in nanoseconds */ uint64_t ndiff(uint64_t begin, uint64_t end) { - return (end - begin) * 1000000000 / __procinfo.tsc_freq; + return (end - begin) * 1000000000 / __procinfo.tsc_freq; } /* Conversion btw tsc ticks and time units. From Akaros's kern/src/time.c */ @@ -108,3 +110,8 @@ uint64_t nsec2tsc(uint64_t nsec) else return (nsec * get_tsc_freq()) / 1000000000; } + +uint64_t nsec() +{ + return tsc2nsec(read_tsc()); +} -- 2.8.0.rc3.226.g39d4020 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
