+DISPATCH_ALWAYS_INLINE
+static inline dispatch_trace_timer_params_t
+_dispatch_trace_timer_params(dispatch_clock_t clock,
+ struct dispatch_timer_source_s *values, uint64_t deadline,
+ dispatch_trace_timer_params_t params)
+{
+ #define _dispatch_trace_time2nano3(t) \
+ (clock == DISPATCH_CLOCK_MACH ? _dispatch_time_mach2nano(t) : (t))
+ #define _dispatch_trace_time2nano2(v, t) ({ uint64_t _t = (t); \
+ (v) >= INT64_MAX ? -1ll : (int64_t)_dispatch_trace_time2nano3(_t);})
+ #define _dispatch_trace_time2nano(v) ({ uint64_t _t; \
+ _t = _dispatch_trace_time2nano3(v); _t >= INT64_MAX ? -1ll : \
+ (int64_t)_t; })
+ if (deadline) {
+ params->deadline = (int64_t)deadline;
+ } else {
+ uint64_t now = _dispatch_time_now(clock);
+ params->deadline = _dispatch_trace_time2nano2(values->target,
+ values->target < now ? 0 : values->target - now);
+ }
+ uint64_t leeway = values->deadline - values->target;
+ params->interval = _dispatch_trace_time2nano(values->interval);
+ params->leeway = _dispatch_trace_time2nano(leeway);
+ return params;
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline bool
+_dispatch_trace_timer_configure_enabled(void)
+{
+ return slowpath(DISPATCH_TIMER_CONFIGURE_ENABLED());
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_trace_timer_configure(dispatch_source_t ds, dispatch_clock_t clock,
+ struct dispatch_timer_source_s *values)
+{
+ dispatch_timer_source_refs_t dr = ds->ds_timer_refs;
+ struct dispatch_trace_timer_params_s params;
+ DISPATCH_TIMER_CONFIGURE(ds, _dispatch_trace_timer_function(dr),
+ _dispatch_trace_timer_params(clock, values, 0, ¶ms));
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_trace_timer_program(dispatch_timer_source_refs_t dr, uint64_t deadline)
+{
+ if (slowpath(DISPATCH_TIMER_PROGRAM_ENABLED())) {
+ if (deadline && dr) {
+ dispatch_source_t ds = _dispatch_source_from_refs(dr);
+ dispatch_clock_t clock = DISPATCH_TIMER_CLOCK(dr->du_ident);
+ struct dispatch_trace_timer_params_s params;
+ DISPATCH_TIMER_PROGRAM(ds, _dispatch_trace_timer_function(dr),
+ _dispatch_trace_timer_params(clock, &dr->dt_timer,
+ deadline, ¶ms));
+ }
+ }
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_trace_timer_wake(dispatch_timer_source_refs_t dr)
+{
+ if (slowpath(DISPATCH_TIMER_WAKE_ENABLED())) {
+ if (dr) {
+ dispatch_source_t ds = _dispatch_source_from_refs(dr);
+ DISPATCH_TIMER_WAKE(ds, _dispatch_trace_timer_function(dr));
+ }
+ }
+}
+
+DISPATCH_ALWAYS_INLINE
+static inline void
+_dispatch_trace_timer_fire(dispatch_timer_source_refs_t dr, uint64_t data,
+ uint64_t missed)
+{
+ if (slowpath(DISPATCH_TIMER_FIRE_ENABLED())) {
+ if (!(data - missed) && dr) {
+ dispatch_source_t ds = _dispatch_source_from_refs(dr);
+ DISPATCH_TIMER_FIRE(ds, _dispatch_trace_timer_function(dr));
+ }
+ }
+}
+
+#else
+
+#define _dispatch_trace_timer_configure_enabled() false
+#define _dispatch_trace_timer_configure(ds, clock, values) \
+ do { (void)(ds); (void)(clock); (void)(values); } while(0)
+#define _dispatch_trace_timer_program(dr, deadline) \
+ do { (void)(dr); (void)(deadline); } while(0)
+#define _dispatch_trace_timer_wake(dr) \
+ do { (void)(dr); } while(0)
+#define _dispatch_trace_timer_fire(dr, data, missed) \
+ do { (void)(dr); (void)(data); (void)(missed); } while(0)