34#ifndef _ACF_UTILS_DELAY_LINE_H_
35#define _ACF_UTILS_DELAY_LINE_H_
70 uint64_t delay_base_us;
71 double delay_rand_fract;
73 int __serialize_marker[0];
76 int __serialize_marker[1];
79 void *time_func_userinfo;
92 memset(line, 0,
sizeof (*line));
93 line->delay_us = delay_us;
94 line->delay_base_us = delay_us;
95 line->delay_rand_fract = 0;
114 memset(line, 0,
sizeof (*line));
115 line->delay_us = delay_us;
116 line->delay_base_us = delay_us;
117 line->delay_rand_fract = 0;
118 line->time_func = time_func;
119 line->time_func_userinfo = time_func_userinfo;
131 if (line->delay_rand_fract == 0) {
132 line->delay_us = line->delay_base_us;
134 uint64_t rand_us = line->delay_rand_fract * line->delay_base_us;
135 line->delay_us = line->delay_base_us +
147 if (line->delay_base_us != delay_us) {
148 line->delay_base_us = delay_us;
158static inline uint64_t
162 return (line->delay_base_us);
171static inline uint64_t
175 return (line->delay_us);
197 line->delay_rand_fract = rand_fract;
209 return (line->delay_rand_fract);
212#define DEF_DELAY_LINE_PULL(typename, abbrev_type) \
213static inline typename \
214delay_line_pull_ ## abbrev_type(delay_line_t *line) \
217 ASSERT(line != NULL); \
218 now = (line->time_func != NULL ? \
219 line->time_func(line->time_func_userinfo) : microclock()); \
220 if (line->abbrev_type ## _new != line->abbrev_type && \
221 now - line->changed_t >= line->delay_us) { \
222 line->abbrev_type = line->abbrev_type ## _new; \
223 delay_line_refresh_delay(line); \
225 return (line->abbrev_type); \
234DEF_DELAY_LINE_PULL(int64_t, i64)
238DEF_DELAY_LINE_PULL(uint64_t, u64)
242DEF_DELAY_LINE_PULL(
double, f64)
244#define DEF_DELAY_LINE_PEEK(typename, abbrev_type) \
245static inline typename \
246delay_line_peek_ ## abbrev_type(const delay_line_t *line) \
248 ASSERT(line != NULL); \
249 return (line->abbrev_type); \
257DEF_DELAY_LINE_PEEK(int64_t, i64)
261DEF_DELAY_LINE_PEEK(uint64_t, u64)
265DEF_DELAY_LINE_PEEK(
double, f64)
272DEF_DELAY_LINE_PEEK(int64_t, i64_new)
276DEF_DELAY_LINE_PEEK(uint64_t, u64_new)
280DEF_DELAY_LINE_PEEK(
double, f64_new)
282#define DEF_DELAY_LINE_PUSH(typename, abbrev_type) \
283static inline typename \
284delay_line_push_ ## abbrev_type(delay_line_t *line, typename value) \
287 ASSERT(line != NULL); \
288 now = (line->time_func != NULL ? \
289 line->time_func(line->time_func_userinfo) : microclock()); \
290 if (line->abbrev_type == line->abbrev_type ## _new && \
291 value != line->abbrev_type ## _new) { \
292 line->changed_t = now; \
293 delay_line_refresh_delay(line); \
295 line->abbrev_type ## _new = value; \
296 return (delay_line_pull_ ## abbrev_type(line)); \
306DEF_DELAY_LINE_PUSH(int64_t, i64)
310DEF_DELAY_LINE_PUSH(uint64_t, u64)
314DEF_DELAY_LINE_PUSH(
double, f64)
316#define DEF_DELAY_LINE_PUSH_IMM(typename, abbrev_type) \
317static inline typename \
318delay_line_push_imm_ ## abbrev_type(delay_line_t *line, typename value) \
320 ASSERT(line != NULL); \
321 line->abbrev_type = value; \
322 line->abbrev_type ## _new = value; \
323 return (line->abbrev_type); \
329DEF_DELAY_LINE_PUSH_IMM(int64_t, i64)
333DEF_DELAY_LINE_PUSH_IMM(uint64_t, u64)
337DEF_DELAY_LINE_PUSH_IMM(
double, f64)
355#if __STDC_VERSION__ >= 201112L
356#define DELAY_LINE_PUSH(line, value) \
358 float: delay_line_push_f64((line), (value)), \
359 double: delay_line_push_f64((line), (value)), \
360 uint32_t: delay_line_push_u64((line), (value)), \
361 uint64_t: delay_line_push_u64((line), (value)), \
362 default: delay_line_push_i64((line), (value)))
363#define DELAY_LINE_PUSH_IMM(line, value) \
365 float: delay_line_push_imm_f64((line), (value)), \
366 double: delay_line_push_imm_f64((line), (value)), \
367 uint32_t: delay_line_push_imm_u64((line), (value)), \
368 uint64_t: delay_line_push_imm_u64((line), (value)), \
369 default: delay_line_push_imm_i64((line), (value)))
371#define DELAY_LINE_PUSH(line, value) \
372 DELAY_LINE_PUSH_macro_requires_C11_or_greater
373#define DELAY_LINE_PUSH_IMM(line, value) \
374 DELAY_LINE_PUSH_IMM_macro_requires_C11_or_greater
387static inline uint64_t
392 now = (line->time_func != NULL ?
393 line->time_func(line->time_func_userinfo) : microclock());
394 return (now - line->changed_t);
#define ASSERT3F(x, op, y)
API_EXPORT double crc64_rand_fract(void)
static uint64_t delay_line_get_delay(const delay_line_t *line)
static void delay_line_set_rand(delay_line_t *line, double rand_fract)
static void delay_line_refresh_delay(delay_line_t *line)
uint64_t(* delay_line_time_func_t)(void *userinfo)
static double delay_line_get_rand(const delay_line_t *line)
static uint64_t delay_line_get_delay_act(const delay_line_t *line)
static void delay_line_init(delay_line_t *line, uint64_t delay_us)
static uint64_t delay_line_get_time_since_change(const delay_line_t *line)
static void delay_line_init_time_func(delay_line_t *line, uint64_t delay_us, delay_line_time_func_t time_func, void *time_func_userinfo)
static void delay_line_set_delay(delay_line_t *line, uint64_t delay_us)