/* The nanoseconds add-on to GC_time_limit */
/* value. Not updated by GC_set_time_limit(). */
/* Ignored if the value of GC_time_limit is */
- /* GC_TIME_UNLIMITED; ignored on some platforms */
- /* (depending on GET_TIME implementation). */
+ /* GC_TIME_UNLIMITED. */
# define TV_NSEC_LIMIT (1000UL * 1000) /* amount of nanoseconds in 1 ms */
{
CLOCK_TYPE current_time;
static unsigned count = 0;
- unsigned long time_diff;
+ unsigned long time_diff, nsec_diff;
if ((*GC_default_stop_func)())
return(1);
if ((count++ & 3) != 0) return(0);
GET_TIME(current_time);
time_diff = MS_TIME_DIFF(current_time,GC_start_time);
- if (time_diff >= GC_time_limit) {
- GC_COND_LOG_PRINTF(
- "Abandoning stopped marking after %lu ms (attempt %d)\n",
- time_diff, GC_n_attempts);
- return(1);
+ nsec_diff = NS_FRAC_TIME_DIFF(current_time, GC_start_time);
+ if (time_diff >= GC_time_limit
+ && (time_diff > GC_time_limit || nsec_diff >= GC_time_lim_nsec)) {
+ GC_COND_LOG_PRINTF("Abandoning stopped marking after %lu ms %lu ns"
+ " (attempt %d)\n",
+ time_diff, nsec_diff, GC_n_attempts);
+ return 1;
}
return(0);
}
if (measure_performance)
full_gc_total_time += time_diff; /* may wrap */
if (GC_print_stats)
- GC_log_printf("Complete collection took %lu ms\n", time_diff);
+ GC_log_printf("Complete collection took %lu ms %lu ns\n", time_diff,
+ NS_FRAC_TIME_DIFF(current_time, start_time));
}
# endif
if (GC_on_collection_event)
world_stopped_total_divisor = ++divisor;
GC_ASSERT(divisor != 0);
- GC_log_printf("World-stopped marking took %lu ms (%u in average)\n",
- time_diff, total_time / divisor);
+ GC_log_printf("World-stopped marking took %lu ms %lu ns"
+ " (%u ms in average)\n",
+ time_diff, NS_FRAC_TIME_DIFF(current_time, start_time),
+ total_time / divisor);
}
# endif
return(TRUE);
/* A convenient place to output finalization statistics. */
GC_print_finalization_stats();
# endif
- GC_log_printf("Finalize plus initiate sweep took %lu + %lu ms\n",
- MS_TIME_DIFF(finalize_time,start_time),
- MS_TIME_DIFF(done_time,finalize_time));
+ GC_log_printf("Finalize and initiate sweep took %lu ms %lu ns"
+ " + %lu ms %lu ns\n",
+ MS_TIME_DIFF(finalize_time, start_time),
+ NS_FRAC_TIME_DIFF(finalize_time, start_time),
+ MS_TIME_DIFF(done_time, finalize_time),
+ NS_FRAC_TIME_DIFF(done_time, finalize_time));
}
# elif !defined(SMALL_CONFIG) && !defined(GC_NO_FINALIZATION)
if (GC_print_stats)
x = rusage.ru_utime; \
} while (0)
# define MS_TIME_DIFF(a,b) ((unsigned long)((long)(a.tv_sec-b.tv_sec) * 1000 \
- + (long)(a.tv_usec-b.tv_usec) / 1000))
+ + (long)(a.tv_usec - b.tv_usec) / 1000 \
+ - (a.tv_usec < b.tv_usec \
+ && (long)(a.tv_usec - b.tv_usec) % 1000 != 0 ? 1 : 0)))
/* "a" time is expected to be not earlier than */
/* "b" one; the result has unsigned long type. */
+# define NS_FRAC_TIME_DIFF(a, b) ((unsigned long) \
+ ((a.tv_usec < b.tv_usec \
+ && (long)(a.tv_usec - b.tv_usec) % 1000 != 0 ? 1000L : 0) \
+ + (long)(a.tv_usec - b.tv_usec) % 1000) * 1000)
+ /* The total time difference could be computed as */
+ /* MS_TIME_DIFF(a,b)*1000000+NS_FRAC_TIME_DIFF(a,b).*/
#elif defined(MSWIN32) || defined(MSWINCE)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# define GET_TIME(x) (void)(x = GetTickCount())
# endif
# define MS_TIME_DIFF(a,b) ((unsigned long)((a)-(b)))
+# define NS_FRAC_TIME_DIFF(a, b) 0UL
#elif defined(NN_PLATFORM_CTR)
# define CLOCK_TYPE long long
EXTERN_C_BEGIN
EXTERN_C_END
# define GET_TIME(x) (void)(x = n3ds_get_system_tick())
# define MS_TIME_DIFF(a,b) ((unsigned long)n3ds_convert_tick_to_ms((a)-(b)))
+# define NS_FRAC_TIME_DIFF(a, b) 0UL /* TODO: implement it */
#else /* !BSD_TIME && !NN_PLATFORM_CTR && !MSWIN32 && !MSWINCE */
# include <time.h>
# if defined(FREEBSD) && !defined(CLOCKS_PER_SEC)
: ((unsigned long)((a) - (b)) * 1000) / (unsigned long)CLOCKS_PER_SEC)
/* Avoid using double type since some targets (like ARM) might */
/* require -lm option for double-to-long conversion. */
+# define NS_FRAC_TIME_DIFF(a, b) (CLOCKS_PER_SEC <= 1000 ? 0UL \
+ : (unsigned long)(CLOCKS_PER_SEC <= (clock_t)1000000UL \
+ ? (((a) - (b)) * ((clock_t)1000000UL / CLOCKS_PER_SEC) % 1000) * 1000 \
+ : (CLOCKS_PER_SEC <= (clock_t)1000000UL * 1000 \
+ ? ((a) - (b)) * ((clock_t)1000000UL * 1000 / CLOCKS_PER_SEC) \
+ : (((a) - (b)) * (clock_t)1000000UL * 1000) / CLOCKS_PER_SEC) \
+ % (clock_t)1000000UL))
#endif /* !BSD_TIME && !MSWIN32 */
# ifndef CLOCK_TYPE_INITIALIZER
/* This is used to initialize CLOCK_TYPE variables (to some value) */