Skip to content

Commit

Permalink
further signed-vs-unsigned repairs to time handling
Browse files Browse the repository at this point in the history
Changing the result of cpu-time functions to unsigned suggests
further corrections to avoid overflow.
  • Loading branch information
mflatt committed Mar 28, 2020
1 parent 9c2b84d commit 5c77bfc
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 30 deletions.
6 changes: 3 additions & 3 deletions racket/src/racket/include/schthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ typedef struct Thread_Local_Variables {
int current_lifetime_;
int scheme_main_was_once_suspended_;
int buffer_init_size_;
intptr_t scheme_total_gc_time_;
intptr_t start_this_gc_time_;
intptr_t end_this_gc_time_;
uintptr_t scheme_total_gc_time_;
uintptr_t start_this_gc_time_;
uintptr_t end_this_gc_time_;
double start_this_gc_real_time_;
double end_this_gc_real_time_;
struct Scheme_Struct_Type *gc_info_prefab_;
Expand Down
7 changes: 3 additions & 4 deletions racket/src/racket/src/fun.c
Original file line number Diff line number Diff line change
Expand Up @@ -9857,10 +9857,9 @@ static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv)
static Scheme_Object *time_apply(int argc, Scheme_Object *argv[])
{
uintptr_t start, end;
intptr_t cpustart, cpuend;
intptr_t gcstart, gcend;
uintptr_t dur;
intptr_t cpudur, gcdur;
uintptr_t cpustart, cpuend;
uintptr_t gcstart, gcend;
uintptr_t dur, cpudur, gcdur;
int i, num_rands;
Scheme_Object *v, *p[4], **rand_vec, *rands, *r;

Expand Down
2 changes: 1 addition & 1 deletion racket/src/racket/src/schpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[]);

THREAD_LOCAL_DECL(extern struct rktio_t *scheme_rktio);
THREAD_LOCAL_DECL(extern int scheme_current_place_id);
THREAD_LOCAL_DECL(extern intptr_t scheme_total_gc_time);
THREAD_LOCAL_DECL(extern uintptr_t scheme_total_gc_time);
THREAD_LOCAL_DECL(extern int scheme_cont_capture_count);
THREAD_LOCAL_DECL(extern int scheme_continuation_application_count);
THREAD_LOCAL_DECL(extern struct Scheme_Prefix *scheme_prefix_finalize);
Expand Down
6 changes: 3 additions & 3 deletions racket/src/racket/src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ ROSYM Scheme_Object *scheme_break_enabled_key;
THREAD_LOCAL_DECL(static Scheme_Object *configuration_callback_cache[2]);

static int gcs_on_exit;
THREAD_LOCAL_DECL(intptr_t scheme_total_gc_time);
THREAD_LOCAL_DECL(static intptr_t start_this_gc_time);
THREAD_LOCAL_DECL(static intptr_t end_this_gc_time);
THREAD_LOCAL_DECL(uintptr_t scheme_total_gc_time);
THREAD_LOCAL_DECL(static uintptr_t start_this_gc_time);
THREAD_LOCAL_DECL(static uintptr_t end_this_gc_time);
THREAD_LOCAL_DECL(static double start_this_gc_real_time);
THREAD_LOCAL_DECL(static double end_this_gc_real_time);
static void get_ready_for_GC(void);
Expand Down
4 changes: 2 additions & 2 deletions racket/src/rktio/rktio.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ rktio_connect_stop
rktio_poll_connect_ready
rktio_connect_trying
rktio_socket_shutdown
rktio_udp_get_ttl
rktio_udp_set_ttl
rktio_udp_open
rktio_udp_disconnect
rktio_udp_bind
Expand All @@ -66,6 +64,8 @@ rktio_udp_sendto_in
rktio_udp_recvfrom
rktio_udp_recvfrom_in
rktio_udp_set_receive_buffer_size
rktio_udp_set_ttl
rktio_udp_get_ttl
rktio_udp_get_multicast_loopback
rktio_udp_set_multicast_loopback
rktio_udp_get_multicast_ttl
Expand Down
11 changes: 9 additions & 2 deletions racket/src/rktio/rktio.h
Original file line number Diff line number Diff line change
Expand Up @@ -1014,13 +1014,20 @@ typedef struct rktio_date_t {
} rktio_date_t;

RKTIO_EXTERN_NOERR uintptr_t rktio_get_milliseconds(void);
/* Overflow may cause the result to wrap around to 0, at least on a
32-bit platform. */

RKTIO_EXTERN_NOERR double rktio_get_inexact_milliseconds(void);
/* No overflow, but won't strictly increase if the system clock is reset. */

RKTIO_EXTERN_NOERR intptr_t rktio_get_process_milliseconds(rktio_t *rktio);
RKTIO_EXTERN_NOERR intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio);
RKTIO_EXTERN_NOERR uintptr_t rktio_get_process_milliseconds(rktio_t *rktio);
RKTIO_EXTERN_NOERR uintptr_t rktio_get_process_children_milliseconds(rktio_t *rktio);
/* Overflow may cause the result to wrap around to 0, at least on a
32-bit platform. */

RKTIO_EXTERN_NOERR rktio_timestamp_t rktio_get_seconds(rktio_t *rktio);
RKTIO_EXTERN rktio_date_t *rktio_seconds_to_date(rktio_t *rktio, rktio_timestamp_t seconds, int nanoseconds, int get_gmt);
/* A timestamp can be negative to represent a date before 1970. */

/*************************************************/
/* Windows ShellExecute */
Expand Down
2 changes: 1 addition & 1 deletion racket/src/rktio/rktio.inc
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ Sforeign_symbol("rktio_udp_sendto_in", (void *)rktio_udp_sendto_in);
Sforeign_symbol("rktio_udp_recvfrom", (void *)rktio_udp_recvfrom);
Sforeign_symbol("rktio_udp_recvfrom_in", (void *)rktio_udp_recvfrom_in);
Sforeign_symbol("rktio_udp_set_receive_buffer_size", (void *)rktio_udp_set_receive_buffer_size);
Sforeign_symbol("rktio_udp_get_ttl", (void *)rktio_udp_get_ttl);
Sforeign_symbol("rktio_udp_set_ttl", (void *)rktio_udp_set_ttl);
Sforeign_symbol("rktio_udp_get_ttl", (void *)rktio_udp_get_ttl);
Sforeign_symbol("rktio_udp_get_multicast_loopback", (void *)rktio_udp_get_multicast_loopback);
Sforeign_symbol("rktio_udp_set_multicast_loopback", (void *)rktio_udp_set_multicast_loopback);
Sforeign_symbol("rktio_udp_get_multicast_ttl", (void *)rktio_udp_get_multicast_ttl);
Expand Down
6 changes: 3 additions & 3 deletions racket/src/rktio/rktio.rktl
Original file line number Diff line number Diff line change
Expand Up @@ -1182,16 +1182,16 @@
rktio_install_os_signal_handler
(((ref rktio_t) rktio)))
(define-function () int rktio_poll_os_signal (((ref rktio_t) rktio)))
(define-function () intptr_t rktio_get_milliseconds ())
(define-function () uintptr_t rktio_get_milliseconds ())
(define-function () double rktio_get_inexact_milliseconds ())
(define-function
()
intptr_t
uintptr_t
rktio_get_process_milliseconds
(((ref rktio_t) rktio)))
(define-function
()
intptr_t
uintptr_t
rktio_get_process_children_milliseconds
(((ref rktio_t) rktio)))
(define-function
Expand Down
25 changes: 14 additions & 11 deletions racket/src/rktio/rktio_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ uintptr_t rktio_get_milliseconds(void)
/* this function can be called from any OS thread */
{
#ifdef RKTIO_SYSTEM_WINDOWS
return (intptr_t)(get_hectonanoseconds_as_longlong() / (rktio_int64_t)10000);
return (uintptr_t)(get_hectonanoseconds_as_longlong() / (rktio_int64_t)10000);
#else
struct timeval now;
gettimeofday(&now, NULL);
Expand All @@ -107,22 +107,22 @@ double rktio_get_inexact_milliseconds(void)
#endif
}

intptr_t rktio_get_process_milliseconds(rktio_t *rktio)
uintptr_t rktio_get_process_milliseconds(rktio_t *rktio)
{
#ifdef USER_TIME_IS_CLOCK
return scheme_get_milliseconds();
#else
# ifdef USE_GETRUSAGE
struct rusage use;
intptr_t s, u;
uintptr_t s, u;

do {
if (!getrusage(RUSAGE_SELF, &use))
break;
} while (errno == EINTR);

s = use.ru_utime.tv_sec + use.ru_stime.tv_sec;
u = use.ru_utime.tv_usec + use.ru_stime.tv_usec;
s = (uintptr_t)use.ru_utime.tv_sec + (uintptr_t)use.ru_stime.tv_sec;
u = (uintptr_t)use.ru_utime.tv_usec + (uintptr_t)use.ru_stime.tv_usec;

return s * 1000 + u / 1000;
# else
Expand All @@ -138,29 +138,30 @@ intptr_t rktio_get_process_milliseconds(rktio_t *rktio)
return 0; /* anything better to do? */
}
# else
return clock() * 1000 / CLOCKS_PER_SEC;

/* Hoping that `clock_t` cannot overflow or is unsigned to avoid
undefined behavior on overflow... */
return clock() * 1000 / CLOCKS_PER_SEC;
# endif
# endif
#endif
}

intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio)
uintptr_t rktio_get_process_children_milliseconds(rktio_t *rktio)
{
#ifdef USER_TIME_IS_CLOCK
return 0;
#else
# ifdef USE_GETRUSAGE
struct rusage use;
intptr_t s, u;
uintptr_t s, u;

do {
if (!getrusage(RUSAGE_CHILDREN, &use))
break;
} while (errno == EINTR);

s = use.ru_utime.tv_sec + use.ru_stime.tv_sec;
u = use.ru_utime.tv_usec + use.ru_stime.tv_usec;
s = (uintptr_t)use.ru_utime.tv_sec + (uintptr_t)use.ru_stime.tv_sec;
u = (uintptr_t)use.ru_utime.tv_usec + (uintptr_t)use.ru_stime.tv_usec;

return (s * 1000 + u / 1000);
# else
Expand All @@ -169,6 +170,8 @@ intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio)
# else
clock_t t;
times(&t);
/* Hoping that `clock_t` cannot overflow or is unsigned to avoid
undefined behavior on overflow... */
return (t.tms_cutime + t.tms_cstime) * 1000 / CLK_TCK;
# endif
# endif
Expand Down

0 comments on commit 5c77bfc

Please sign in to comment.