#endif
#ifndef NO_CLOCK
+ STATIC unsigned long GC_time_lim_nsec = 0;
+ /* 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). */
+
+# define TV_NSEC_LIMIT (1000UL * 1000) /* amount of nanoseconds in 1 ms */
+
+ GC_API void GC_CALL GC_set_time_limit_tv(struct GC_timeval_s tv)
+ {
+ GC_ASSERT(tv.tv_ms <= GC_TIME_UNLIMITED);
+ GC_ASSERT(tv.tv_nsec < TV_NSEC_LIMIT);
+ GC_time_limit = tv.tv_ms;
+ GC_time_lim_nsec = tv.tv_nsec;
+ }
+
+ GC_API struct GC_timeval_s GC_CALL GC_get_time_limit_tv(void)
+ {
+ struct GC_timeval_s tv;
+
+ tv.tv_ms = GC_time_limit;
+ tv.tv_nsec = GC_time_lim_nsec;
+ return tv;
+ }
+
STATIC CLOCK_TYPE GC_start_time = CLOCK_TYPE_INITIALIZER;
/* Time at which we stopped world. */
/* used only in GC_timeout_stop_func. */
-#endif
+#endif /* !NO_CLOCK */
STATIC int GC_n_attempts = 0; /* Number of attempts at finishing */
/* collection within GC_time_limit. */
GC_API GC_ATTR_DEPRECATED unsigned long GC_time_limit;
/* If incremental collection is enabled, */
- /* We try to terminate collections */
- /* after this many milliseconds. Not a */
- /* hard time bound. Setting this to */
+ /* we try to terminate collections */
+ /* after this many milliseconds (plus */
+ /* the amount of nanoseconds as given in */
+ /* the latest GC_set_time_limit_tv call, */
+ /* if any). Not a hard time bound. */
+ /* Setting this variable to */
/* GC_TIME_UNLIMITED will essentially */
/* disable incremental collection while */
/* leaving generational collection */
/* GC_call_with_alloc_lock() is required to */
/* avoid data races (if the value is modified */
/* after the GC is put to multi-threaded mode). */
+ /* The setter does not update the value of the */
+ /* nanosecond part of the time limit (it is */
+ /* zero unless ever set by GC_set_time_limit_tv */
+ /* call). */
GC_API void GC_CALL GC_set_time_limit(unsigned long);
GC_API unsigned long GC_CALL GC_get_time_limit(void);
+/* A portable type definition of time with a nanosecond precision. */
+struct GC_timeval_s {
+ unsigned long tv_ms; /* time in milliseconds */
+ unsigned long tv_nsec;/* nanoseconds fraction (<1000000) */
+};
+
/* Public procedures */
+/* Set/get the time limit of the incremental collections. This is */
+/* similar to GC_set_time_limit and GC_get_time_limit but the time is */
+/* provided with the nanosecond precision. The value of tv_nsec part */
+/* should be less than a million. If the value of tv_ms part is */
+/* GC_TIME_UNLIMITED then tv_nsec is ignored. Initially, the value of */
+/* tv_nsec part of the time limit is zero. The functions do not use */
+/* any synchronization. Defined only if the library has been compiled */
+/* without NO_CLOCK. */
+GC_API void GC_CALL GC_set_time_limit_tv(struct GC_timeval_s);
+GC_API struct GC_timeval_s GC_CALL GC_get_time_limit_tv(void);
+
/* Tell the collector to start various performance measurements. */
/* Only the total time taken by full collections is calculated, as */
/* of now. And, currently, there is no way to stop the measurements. */
#endif
#if defined(GC_TIME_LIMIT) && !defined(CPPCHECK)
- /* Set GC_time_limit to the desired value at start-up */
+ /* Set GC_time_limit (in ms) to the desired value at start-up. */
# define GC_INIT_CONF_TIME_LIMIT GC_set_time_limit(GC_TIME_LIMIT)
#else
# define GC_INIT_CONF_TIME_LIMIT /* empty */