static void *play_thread(void *arg) { uint64_t now, ts = tmr_jiffies(); struct ausrc_st *st = arg; int16_t *sampv; sampv = mem_alloc(st->sampc * 2, NULL); if (!sampv) return NULL; while (st->run) { sys_msleep(4); now = tmr_jiffies(); if (ts > now) continue; aubuf_read_samp(st->aubuf, sampv, st->sampc); st->rh(sampv, st->sampc, st->arg); ts += st->ptime; } mem_deref(sampv); info("aufile: player thread exited\n"); return NULL; }
void flow_mediaflow_estab(struct flow *flow, const char *crypto, const char *codec, const char *ltype, const char *rtype, const struct sa *sa) { uint64_t now = tmr_jiffies(); struct call *call = flow->call; info("flowmgr(%p): call(%p): flow(%p -- %s): mediaflow established " "est_st=%d crypto=%s codec=%s ice=%s-%s.%J\n", call ? call->fm : NULL, call, flow, flow->flowid, flow->est_st, crypto, codec, ltype, rtype, sa); flow->estab = true; flow->stats.sa = *sa; flow->stats.estab_time = (int)(now - flow->startts); str_ncpy(flow->stats.ltype, ltype, sizeof(flow->stats.ltype)); str_ncpy(flow->stats.rtype, rtype, sizeof(flow->stats.rtype)); str_ncpy(flow->stats.crypto, crypto, sizeof(flow->stats.crypto)); str_ncpy(flow->stats.codec, codec, sizeof(flow->stats.codec)); flow->estabts = tmr_jiffies(); flow->est_st |= FLOWMGR_ESTAB_ICE; flow_estabh(flow); }
static void call_handler(tmr_h *th, void *arg) { const uint64_t tick = tmr_jiffies(); uint32_t diff; /* Call handler */ th(arg); diff = (uint32_t)(tmr_jiffies() - tick); if (diff > MAX_BLOCKING) { DEBUG_WARNING("long async blocking: %u>%u ms (h=%p arg=%p)\n", diff, MAX_BLOCKING, th, arg); } }
/* NOTE: This function should not allocate memory */ static void dbg_vprintf(int level, const char *fmt, va_list ap) { if (level > dbg.level) return; /* Print handler? */ if (dbg.ph) return; dbg_lock(); if (dbg.flags & DBG_ANSI) { switch (level) { case DBG_WARNING: (void)re_fprintf(stderr, "\x1b[31m"); /* Red */ break; case DBG_NOTICE: (void)re_fprintf(stderr, "\x1b[33m"); /* Yellow */ break; case DBG_INFO: (void)re_fprintf(stderr, "\x1b[32m"); /* Green */ break; default: break; } } if (dbg.flags & DBG_TIME) { const uint64_t ticks = tmr_jiffies(); if (0 == dbg.tick) dbg.tick = tmr_jiffies(); (void)re_fprintf(stderr, "[%09llu] ", ticks - dbg.tick); } (void)re_vfprintf(stderr, fmt, ap); if (dbg.flags & DBG_ANSI && level < DBG_DEBUG) (void)re_fprintf(stderr, "\x1b[;m"); dbg_unlock(); }
void call_rtp_started(struct call *call, bool started) { struct flowmgr *fm; if (!call) return; fm = call->fm; debug("flowmgr(%p): call(%p): rtp_started: started=%d->%d\n", fm, call, call->rtp_started, started); if (call->rtp_started == started) return; call->rtp_started = started; if (started && call->rtp_start_ts == 0) { uint64_t t; call->rtp_start_ts = tmr_jiffies(); t = call->rtp_start_ts - call->start_ts; info("flowmgr(%p): call(%p): rtp_started " "total setup time is %llu ms\n", fm, call, t); } }
static int print_system_info(struct re_printf *pf, void *arg) { uint32_t uptime; int err = 0; (void)arg; uptime = (uint32_t)((long long)(tmr_jiffies() - start_ticks)/1000); err |= re_hprintf(pf, "\n--- System info: ---\n"); err |= re_hprintf(pf, " Machine: %s/%s\n", sys_arch_get(), sys_os_get()); err |= re_hprintf(pf, " Version: %s (libre v%s)\n", BARESIP_VERSION, sys_libre_version_get()); err |= re_hprintf(pf, " Build: %H\n", sys_build_get, NULL); err |= re_hprintf(pf, " Kernel: %H\n", sys_kernel_get, NULL); err |= re_hprintf(pf, " Uptime: %H\n", fmt_human_time, &uptime); err |= re_hprintf(pf, " Started: %s", ctime(&start_time)); #ifdef __VERSION__ err |= re_hprintf(pf, " Compiler: %s\n", __VERSION__); #endif #ifdef USE_OPENSSL err |= re_hprintf(pf, " OpenSSL: %s\n", SSLeay_version(SSLEAY_VERSION)); #endif return err; }
/** Handle incoming SR (Sender Report) packet */ static void handle_incoming_sr(struct rtcp_sess *sess, const struct rtcp_msg *msg) { struct rtp_member *mbr; uint32_t i; mbr = get_member(sess, msg->r.sr.ssrc); if (!mbr) { DEBUG_WARNING("0x%08x: could not add member\n", msg->r.sr.ssrc); return; } if (mbr->s) { /* Save time when SR was received */ mbr->s->sr_recv = tmr_jiffies(); /* Save NTP timestamp from SR */ mbr->s->last_sr.hi = msg->r.sr.ntp_sec; mbr->s->last_sr.lo = msg->r.sr.ntp_frac; mbr->s->rtp_ts = msg->r.sr.rtp_ts; mbr->s->psent = msg->r.sr.psent; mbr->s->osent = msg->r.sr.osent; } for (i=0; i<msg->hdr.count; i++) handle_rr_block(sess, mbr, &msg->r.sr.rrv[i]); }
bool flow_stats_handler(char *key, void *val, void *arg) { struct json_object *jobj = arg; struct flow *flow = val; struct mflow_stats *stats; uint64_t mtime; if (!flow->estab) return false; mtime = tmr_jiffies() - flow->estabts; stats = &flow->stats; json_object_object_add(jobj, "estab_time", json_object_new_int(stats->estab_time)); json_object_object_add(jobj, "local_candidate", json_object_new_string(stats->ltype)); json_object_object_add(jobj, "remote_candidate", json_object_new_string(stats->rtype)); json_object_object_add(jobj, "media_time", json_object_new_int((int)mtime)); json_object_object_add(jobj, "codec", json_object_new_string(stats->codec)); json_object_object_add(jobj, "crypto", json_object_new_string(stats->crypto)); return true; }
static void tls_endpoint_estab_handler(const char *cipher, void *arg) { int err; (void)arg; re_fprintf(stderr, "\r[ %u .. %c ]", tlsperf.count, 0x20 + tlsperf.count % 0x60); if (tls_endpoint_established(tlsperf.ep_cli) && tls_endpoint_established(tlsperf.ep_srv)) { if (tlsperf.count >= tlsperf.num) { tlsperf.ts_estab = tmr_jiffies(); re_printf("\nDONE!\n"); re_printf("cipher: %s\n", cipher); print_report(); re_cancel(); } else { stop_test(); err = start_test(); if (err) abort_test(err); } } }
static void *read_thread(void *arg) { struct vidsrc_st *st = arg; uint64_t ts = 0; while (st->run) { uint64_t now; sys_msleep(2); now = tmr_jiffies(); if (!ts) ts = now; if (ts > now) continue; process(st); ts += 1000/st->prm.fps; } return NULL; }
/** * Poll all timers in the current thread * * @param tmrl Timer list */ void tmr_poll(struct list *tmrl) { const uint64_t jfs = tmr_jiffies(); for (;;) { struct tmr *tmr; tmr_h *th; void *th_arg; tmr = list_ledata(tmrl->head); if (!tmr || (tmr->jfs > jfs)) { break; } th = tmr->th; th_arg = tmr->arg; tmr->th = NULL; list_unlink(&tmr->le); if (!th) continue; #if TMR_DEBUG call_handler(th, th_arg); #else th(th_arg); #endif } }
/** * Call the application event handler * * @param re Poll state * @param fd File descriptor * @param flags Event flags */ static void fd_handler(struct re *re, int fd, int flags) { const uint64_t tick = tmr_jiffies(); uint32_t diff; DEBUG_INFO("event on fd=%d (flags=0x%02x)...\n", fd, flags); re->fhs[fd].fh(flags, re->fhs[fd].arg); diff = (uint32_t)(tmr_jiffies() - tick); if (diff > MAX_BLOCKING) { DEBUG_WARNING("long async blocking: %u>%u ms (h=%p arg=%p)\n", diff, MAX_BLOCKING, re->fhs[fd].fh, re->fhs[fd].arg); } }
static void metric_start(struct metric *metric) { if (metric->started) return; metric->ts_start = tmr_jiffies(); metric->started = true; }
static void *content_thread(void *arg) { struct vidmix_source *src = arg; struct vidmix *mix = src->mix; uint64_t ts = tmr_jiffies(); pthread_mutex_lock(&src->mutex); while (src->run) { struct le *le; uint64_t now; pthread_mutex_unlock(&src->mutex); (void)usleep(4000); pthread_mutex_lock(&src->mutex); now = tmr_jiffies(); if (ts > now) continue; pthread_rwlock_rdlock(&mix->rwlock); for (le=mix->srcl.head; le; le=le->next) { const struct vidmix_source *lsrc = le->data; if (!lsrc->content || !lsrc->frame_rx || lsrc == src) continue; src->fh((uint32_t)ts * 90, lsrc->frame_rx, src->arg); break; } pthread_rwlock_unlock(&mix->rwlock); ts += src->fint; } pthread_mutex_unlock(&src->mutex); return NULL; }
static void *read_thread(void *arg) { struct vidsrc_st *st = arg; uint64_t ts = tmr_jiffies(); while (st->run) { if (tmr_jiffies() < ts) { sys_msleep(4); continue; } st->frameh(st->frame, st->arg); ts += (1000/st->fps); } return NULL; }
TEST_F(cryptoboxtest, performance) { #define NUM_MESSAGES 1000 #define MSG_SIZE 256 uint64_t t1, t2; struct device *a, *b; size_t len = MSG_SIZE; add_devices(2); connect_devices(); a = (struct device *)devicel.head->data; b = (struct device *)devicel.tail->data; err = device_new_session(a, b); ASSERT_EQ(0, err); uint8_t *msg = (uint8_t *)mem_alloc(len, NULL); rand_bytes(msg, len); re_printf("sending %d messages of size %zu bytes\n", NUM_MESSAGES, len); t1 = tmr_jiffies(); for (int i=0; i<NUM_MESSAGES; i++) { send_message(a, b, msg, len); } t2 = tmr_jiffies(); re_printf("~~~ performance report ~~~\n"); re_printf("num_messages: %d\n", NUM_MESSAGES); re_printf("message_size: %zu\n", len); re_printf("total_time: %d ms\n", (int)(t2-t1)); re_printf("average: %.1f ms\n", 1.0*(t2-t1)/NUM_MESSAGES); re_printf("~~~ ~~~ ~~~ ~~~ ~~~ ~~~ ~~~\n"); re_printf("\n"); mem_deref(msg); }
static uint32_t calc_dlsr(uint64_t sr_recv) { if (sr_recv) { const uint64_t diff = tmr_jiffies() - sr_recv; return (uint32_t)((65536 * diff) / 1000); } else { return 0; } }
static void metric_start(struct metric *metric) { if (metric->started) return; metric->ts_start = tmr_jiffies(); tmr_start(&metric->tmr, 1, tmr_handler, metric); metric->started = true; }
static void *read_thread(void *data) { struct vidsrc_st *st = data; uint64_t now, ts = tmr_jiffies(); while (st->run) { AVPacket pkt; int ret; sys_msleep(4); now = tmr_jiffies(); if (ts > now) continue; av_init_packet(&pkt); ret = av_read_frame(st->ic, &pkt); if (ret < 0) { debug("avformat: rewind stream (ret=%d)\n", ret); sys_msleep(1000); av_seek_frame(st->ic, -1, 0, 0); continue; } if (pkt.stream_index != st->sindex) goto out; handle_packet(st, &pkt); ts += (uint64_t) 1000 * pkt.duration * av_q2d(st->time_base); out: #if LIBAVCODEC_VERSION_INT >= ((57<<16)+(12<<8)+100) av_packet_unref(&pkt); #else av_free_packet(&pkt); #endif } return NULL; }
static void check_all_senders(struct allocator *allocator) { uint64_t now = tmr_jiffies(); struct le *le; for (le = allocator->allocl.head; le; le = le->next) { struct allocation *alloc = le->data; sender_tick(alloc->sender, now); } }
/** * Get the time left until timer expires * * @param tmr Timer object * * @return Time in [ms] until expiration */ uint64_t tmr_get_expire(const struct tmr *tmr) { uint64_t jfs; if (!tmr || !tmr->th) return 0; jfs = tmr_jiffies(); return (tmr->jfs > jfs) ? (tmr->jfs - jfs) : 0; }
uint32_t metric_avg_bitrate(const struct metric *metric) { int diff; if (!metric || !metric->ts_start) return 0; diff = (int)(tmr_jiffies() - metric->ts_start); return 1000 * 8 * metric->n_bytes / diff; }
static int module_init(void) { int err; start_ticks = tmr_jiffies(); (void)time(&start_time); err = cmd_register(baresip_commands(), debugcmdv, ARRAY_SIZE(debugcmdv)); return err; }
static void *play_thread(void *arg) { uint64_t now, ts = tmr_jiffies(); struct ausrc_st *st = arg; int16_t *sampv; sampv = mem_alloc(st->sampc * 2, NULL); if (!sampv) return NULL; while (st->run) { sys_msleep(4); now = tmr_jiffies(); if (ts > now) continue; #if 1 if (now > ts + 100) { debug("aufile: cpu lagging behind (%llu ms)\n", now - ts); } #endif aubuf_read_samp(st->aubuf, sampv, st->sampc); st->rh(sampv, st->sampc, st->arg); ts += st->ptime; } mem_deref(sampv); info("aufile: player thread exited\n"); return NULL; }
/** * Get number of milliseconds until the next timer expires * * @param tmrl Timer-list * * @return Number of [ms], or 0 if no active timers */ uint64_t tmr_next_timeout(struct list *tmrl) { const uint64_t jif = tmr_jiffies(); const struct tmr *tmr; tmr = list_ledata(tmrl->head); if (!tmr) return 0; if (tmr->jfs <= jif) return 1; else return tmr->jfs - jif; }
static void tmr_handler(void *arg) { struct panel *panel = arg; uint64_t now = tmr_jiffies(); tmr_start(&panel->tmr, 2000, tmr_handler, panel); if (panel->ts) { panel->fps = 1000.0 * panel->nframes / (now - panel->ts); } panel->nframes = 0; panel->ts = now; }
static void *play_thread(void *arg) { uint64_t now, ts = tmr_jiffies(); struct ausrc_st *st = arg; void *sampv; size_t num_bytes = st->sampc * st->sampsz; sampv = mem_alloc(num_bytes, NULL); if (!sampv) return NULL; while (st->run) { sys_msleep(4); now = tmr_jiffies(); if (ts > now) continue; #if 1 if (now > ts + 100) { debug("rst: cpu lagging behind (%u ms)\n", now - ts); } #endif aubuf_read(st->aubuf, sampv, num_bytes); st->rh(sampv, st->sampc, st->arg); ts += st->ptime; } mem_deref(sampv); return NULL; }
/** * Start a timer * * @param tmr Timer to start * @param delay Timer delay in [ms] * @param th Timeout handler * @param arg Handler argument */ void tmr_start(struct tmr *tmr, uint64_t delay, tmr_h *th, void *arg) { struct list *tmrl = tmrl_get(); struct le *le; if (!tmr) return; if (tmr->th) { list_unlink(&tmr->le); } tmr->th = th; tmr->arg = arg; if (!th) return; tmr->jfs = delay + tmr_jiffies(); if (delay == 0) { le = list_apply(tmrl, true, inspos_handler_0, &tmr->jfs); if (le) { list_insert_before(tmrl, le, &tmr->le, tmr); } else { list_append(tmrl, &tmr->le, tmr); } } else { le = list_apply(tmrl, false, inspos_handler, &tmr->jfs); if (le) { list_insert_after(tmrl, le, &tmr->le, tmr); } else { list_prepend(tmrl, &tmr->le, tmr); } } #ifdef HAVE_ACTSCHED /* TODO: this is a hack. when a new timer is started we must reset the main sleeping timer in actsched.cpp */ { extern void actsched_restart_timer(void); actsched_restart_timer(); } #endif }
void rtcp_sess_rx_rtp(struct rtcp_sess *sess, uint16_t seq, uint32_t ts, uint32_t ssrc, size_t payload_size, const struct sa *peer) { struct rtp_member *mbr; if (!sess) return; mbr = get_member(sess, ssrc); if (!mbr) { DEBUG_NOTICE("could not add member: 0x%08x\n", ssrc); return; } if (!mbr->s) { mbr->s = mem_zalloc(sizeof(*mbr->s), NULL); if (!mbr->s) { DEBUG_NOTICE("could not add sender: 0x%08x\n", ssrc); return; } /* first packet - init sequence number */ source_init_seq(mbr->s, seq); mbr->s->max_seq = seq - 1; /* probation not used */ sa_cpy(&mbr->s->rtp_peer, peer); ++sess->senderc; } if (!source_update_seq(mbr->s, seq)) { DEBUG_WARNING("rtp_update_seq() returned 0\n"); } if (sess->srate_rx) { uint32_t ts_arrive; /* Convert from wall-clock time to timestamp units */ ts_arrive = (uint32_t)(tmr_jiffies()) * sess->srate_rx / 1000; source_calc_jitter(mbr->s, ts, ts_arrive); } mbr->s->rtp_rx_bytes += payload_size; }
void stream_enable_rtp_timeout(struct stream *strm, uint32_t timeout_ms) { if (!strm) return; strm->rtp_timeout_ms = timeout_ms; tmr_cancel(&strm->tmr_rtp); if (timeout_ms) { info("stream: Enable RTP timeout (%u milliseconds)\n", timeout_ms); strm->ts_last = tmr_jiffies(); tmr_start(&strm->tmr_rtp, 10, check_rtp_handler, strm); } }