Skip to content

Commit

Permalink
Merge pull request JuliaLang#14170 from omus/millisecond_now
Browse files Browse the repository at this point in the history
RFC: Implementation of now() with milliseconds
  • Loading branch information
stevengj committed Dec 3, 2015
2 parents 94ac62d + c936218 commit 64e5907
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 36 deletions.
5 changes: 3 additions & 2 deletions base/dates/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ end
# Returns unix seconds since 1970-01-01T00:00:00
datetime2unix(dt::DateTime) = (value(dt) - UNIXEPOCH)/1000.0
function now()
tm = Libc.TmStruct(time())
return DateTime(tm.year+1900,tm.month+1,tm.mday,tm.hour,tm.min,tm.sec)
tv = Libc.TimeVal()
tm = Libc.TmStruct(tv.sec)
return DateTime(tm.year+1900,tm.month+1,tm.mday,tm.hour,tm.min,tm.sec,div(tv.usec,1000))
end
today() = Date(now())
now(::Type{UTC}) = unix2datetime(time())
Expand Down
14 changes: 13 additions & 1 deletion base/libc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ flush_cstdio() = ccall(:jl_flush_cstdio, Void, ())
@unix_only systemsleep(s::Real) = ccall(:usleep, Int32, (UInt32,), round(UInt32,s*1e6))
@windows_only systemsleep(s::Real) = (ccall(:Sleep, stdcall, Void, (UInt32,), round(UInt32,s*1e3)); return Int32(0))

immutable TimeVal
sec::Int64
usec::Int64
end

function TimeVal()
tv = Ref{TimeVal}()
status = ccall(:jl_gettimeofday, Cint, (Ref{TimeVal},), tv)
status != 0 && error("unable to determine current time: ", status)
return tv[]
end

type TmStruct
sec::Int32
min::Int32
Expand Down Expand Up @@ -143,7 +155,7 @@ end

# system date in seconds
time(tm::TmStruct) = Float64(ccall(:mktime, Int, (Ptr{TmStruct},), &tm))
time() = ccall(:clock_now, Float64, ())
time() = ccall(:jl_clock_now, Float64, ())

## process-related functions ##

Expand Down
2 changes: 1 addition & 1 deletion base/version.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function banner(io::IO = STDOUT)
elseif GIT_VERSION_INFO.commit == ""
commit_string = ""
else
days = Int(floor((ccall(:clock_now, Float64, ()) - GIT_VERSION_INFO.fork_master_timestamp) / (60 * 60 * 24)))
days = Int(floor((ccall(:jl_clock_now, Float64, ()) - GIT_VERSION_INFO.fork_master_timestamp) / (60 * 60 * 24)))
days = max(0, days)
unit = days == 1 ? "day" : "days"
distance = GIT_VERSION_INFO.fork_master_distance
Expand Down
2 changes: 1 addition & 1 deletion src/flisp/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ static value_t fl_time_now(value_t *args, u_int32_t nargs)
{
argcount("time.now", nargs, 0);
(void)args;
return mk_double(clock_now());
return mk_double(jl_clock_now());
}

static value_t fl_path_cwd(value_t *args, uint32_t nargs)
Expand Down
18 changes: 9 additions & 9 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1355,29 +1355,29 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
static void gc_sweep_once(int sweep_mask)
{
#ifdef GC_TIME
double t0 = clock_now();
double t0 = jl_clock_now();
mallocd_array_total = 0;
mallocd_array_freed = 0;
#endif
sweep_malloced_arrays();
#ifdef GC_TIME
jl_printf(JL_STDOUT, "GC sweep arrays %.2f (freed %d/%d)\n", (clock_now() - t0)*1000, mallocd_array_freed, mallocd_array_total);
t0 = clock_now();
jl_printf(JL_STDOUT, "GC sweep arrays %.2f (freed %d/%d)\n", (jl_clock_now() - t0)*1000, mallocd_array_freed, mallocd_array_total);
t0 = jl_clock_now();
big_total = 0;
big_freed = 0;
big_reset = 0;
#endif
sweep_big(sweep_mask);
#ifdef GC_TIME
jl_printf(JL_STDOUT, "GC sweep big %.2f (freed %d/%d with %d rst)\n", (clock_now() - t0)*1000, big_freed, big_total, big_reset);
jl_printf(JL_STDOUT, "GC sweep big %.2f (freed %d/%d with %d rst)\n", (jl_clock_now() - t0)*1000, big_freed, big_total, big_reset);
#endif
}

// returns 0 if not finished
static int gc_sweep_inc(int sweep_mask)
{
#ifdef GC_TIME
double t0 = clock_now();
double t0 = jl_clock_now();
#endif
skipped_pages = 0;
total_pages = 0;
Expand Down Expand Up @@ -1430,7 +1430,7 @@ static int gc_sweep_inc(int sweep_mask)
}

#ifdef GC_TIME
double sweep_pool_sec = clock_now() - t0;
double sweep_pool_sec = jl_clock_now() - t0;
double sweep_speed = ((((double)total_pages)*GC_PAGE_SZ)/(1024*1024*1024))/sweep_pool_sec;
jl_printf(JL_STDOUT, "GC sweep pools %s %.2f at %.1f GB/s (skipped %d%% of %d, done %d pgs, %d freed with %d lazily) mask %d\n", finished ? "end" : "inc", sweep_pool_sec*1000, sweep_speed, total_pages ? (skipped_pages*100)/total_pages : 0, total_pages, page_done, freed_pages, lazy_freed_pages, sweep_mask);
#endif
Expand Down Expand Up @@ -1847,7 +1847,7 @@ static void visit_mark_stack(int mark_mode)
void jl_mark_box_caches(void);

#if defined(GCTIME) || defined(GC_FINAL_STATS)
double clock_now(void);
double jl_clock_now(void);
#endif

extern jl_module_t *jl_old_base_module;
Expand Down Expand Up @@ -2407,7 +2407,7 @@ void jl_print_gc_stats(JL_STREAM *s)
{
double gct = total_gc_time/1e9;
malloc_stats();
double ptime = clock_now()-process_t0;
double ptime = jl_clock_now()-process_t0;
jl_printf(s, "exec time\t%.5f sec\n", ptime);
if (n_pause > 0) {
jl_printf(s, "gc time \t%.5f sec (%2.1f%%) in %d (%d full) collections\n",
Expand Down Expand Up @@ -2489,7 +2489,7 @@ void jl_gc_init(void)
}
#endif
#ifdef GC_FINAL_STATS
process_t0 = clock_now();
process_t0 = jl_clock_now();
#endif

#ifdef _P64
Expand Down
1 change: 0 additions & 1 deletion src/julia.expmap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
__stack_chk_guard;
asprintf;
bitvector_*;
clock_now;
ev_break;
get_exename;
getlocalip;
Expand Down
36 changes: 16 additions & 20 deletions src/support/timefuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,27 @@
extern "C" {
#endif

#if defined(_OS_WINDOWS_)
static double floattime(void)
JL_DLLEXPORT int jl_gettimeofday(struct jl_timeval *jtv)
{
struct timeb tstruct;

ftime(&tstruct);
return (double)tstruct.time + (double)tstruct.millitm/1.0e3;
}
#if defined(_OS_WINDOWS_)
struct __timeb64 tb;
errno_t code = _ftime64_s(&tb);
jtv->sec = tb.time;
jtv->usec = tb.millitm * 1000;
#else
static double tv2float(struct timeval *tv)
{
return (double)tv->tv_sec + (double)tv->tv_usec/1.0e6;
}
struct timeval tv;
int code = gettimeofday(&tv, NULL);
jtv->sec = tv.tv_sec;
jtv->usec = tv.tv_usec;
#endif
return code;
}

double clock_now(void)
JL_DLLEXPORT double jl_clock_now(void)
{
#if defined(_OS_WINDOWS_)
return floattime();
#else
struct timeval now;

gettimeofday(&now, NULL);
return tv2float(&now);
#endif
struct jl_timeval now;
jl_gettimeofday(&now);
return now.sec + now.usec * 1e-6;
}

void sleep_ms(int ms)
Expand Down
8 changes: 7 additions & 1 deletion src/support/timefuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
extern "C" {
#endif

JL_DLLEXPORT double clock_now(void);
struct jl_timeval {
int64_t sec; /* seconds */
int64_t usec; /* microseconds */
};

JL_DLLEXPORT int jl_gettimeofday(struct jl_timeval *jtv);
JL_DLLEXPORT double jl_clock_now(void);
void sleep_ms(int ms);

#ifdef __cplusplus
Expand Down
5 changes: 5 additions & 0 deletions test/dates/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
@test typeof(Dates.today()) <: Dates.Date
@test typeof(Dates.now(Dates.UTC)) <: Dates.DateTime

@osx_only withenv("TZ" => "UTC") do
@test abs(Dates.now() - now(Dates.UTC)) < Dates.Second(1)
end
@test abs(Dates.now() - now(Dates.UTC)) < Dates.Hour(16)

# Issue #9171, #9169
let t = Dates.Period[Dates.Week(2), Dates.Day(14), Dates.Hour(14*24), Dates.Minute(14*24*60), Dates.Second(14*24*60*60), Dates.Millisecond(14*24*60*60*1000)]
for i = 1:length(t)
Expand Down

0 comments on commit 64e5907

Please sign in to comment.