static void rtpp_anetio_sthread(struct sthread_args *args) { int n, nsend, i; struct rtpp_wi *wi, *wis[100]; #ifdef RTPP_DEBUG double tp[3], runtime, sleeptime; long run_n; runtime = sleeptime = 0.0; run_n = 0; tp[0] = getdtime(); #endif for (;;) { nsend = rtpp_queue_get_items(args->out_q, wis, 100, 0); #ifdef RTPP_DEBUG tp[1] = getdtime(); #endif for (i = 0; i < nsend; i++) { wi = wis[i]; if (wi->wi_type == RTPP_WI_TYPE_SGNL) { rtpp_wi_free(wi); goto out; } do { n = sendto(wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen); if (wi->debug != 0) { rtpp_log_write(RTPP_LOG_DBUG, args->glog, "rtpp_anetio_sthread: sendto(%d, %p, %d, %d, %p, %d) = %d", wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen, n); } if (n >= 0) { wi->nsend--; } else if (n == -1 && errno != ENOBUFS) { break; } } while (wi->nsend > 0); rtpp_wi_free(wi); } #ifdef RTPP_DEBUG sleeptime += tp[1] - tp[0]; tp[0] = getdtime(); runtime += tp[0] - tp[1]; if ((run_n % 10000) == 0) { rtpp_log_write(RTPP_LOG_DBUG, args->glog, "rtpp_anetio_sthread(%p): run %ld aload = %f filtered = %f", \ args, run_n, runtime / (runtime + sleeptime), args->average_load.lastval); } if (runtime + sleeptime > 1.0) { recfilter_apply(&args->average_load, runtime / (runtime + sleeptime)); runtime = sleeptime = 0.0; } run_n += 1; #endif } out: return; }
static void rtpp_proc_async_run(void *arg) { struct cfg *cf; double last_tick_time; int alarm_tick, i, ndrain, rtp_only; struct rtpp_proc_async_cf *proc_cf; long long ncycles_ref; #ifdef RTPP_DEBUG int ncycles_ref_pre, last_ctick; #endif struct sign_arg *s_a; struct rtpp_wi *wi, *wis[10]; struct sthread_args *sender; double tp[4]; struct rtpp_proc_rstats *rstats; struct rtpp_stats_obj *stats_cf; cf = (struct cfg *)arg; proc_cf = cf->stable->rtpp_proc_cf; stats_cf = cf->stable->rtpp_stats; rstats = &proc_cf->rstats; last_tick_time = 0; wi = rtpp_queue_get_item(proc_cf->time_q, 0); s_a = (struct sign_arg *)rtpp_wi_sgnl_get_data(wi, NULL); #ifdef RTPP_DEBUG last_ctick = s_a->clock_tick; ncycles_ref_pre = s_a->ncycles_ref; #endif rtpp_wi_free(wi); tp[0] = getdtime(); for (;;) { i = rtpp_queue_get_items(proc_cf->time_q, wis, 10, 0); if (i <= 0) { continue; } i -= 1; s_a = (struct sign_arg *)rtpp_wi_sgnl_get_data(wis[i], NULL); ndrain = (s_a->ncycles_ref - ncycles_ref) / (cf->stable->target_pfreq / MAX_RTP_RATE); #ifdef RTPP_DEBUG last_ctick = s_a->clock_tick; ncycles_ref_pre = ncycles_ref; #endif ncycles_ref = s_a->ncycles_ref; for(; i > -1; i--) { rtpp_wi_free(wis[i]); } tp[1] = getdtime(); #if RTPP_DEBUG if (last_ctick % (unsigned int)cf->stable->target_pfreq == 0 || last_ctick < 1000) { rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld sptime %f, CSV: %f,%f,%f", \ last_ctick, tp[1], (double)last_ctick / cf->stable->target_pfreq, \ ((double)ncycles_ref / cf->stable->target_pfreq) - tp[1], tp[1]); } #endif if (ndrain < 1) { ndrain = 1; } #if RTPP_DEBUG if (ndrain > 1) { rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld " \ "ncycles_ref %lld, ncycles_ref_pre %lld, ndrain %d CSV: %f,%f,%d", \ last_ctick, ncycles_ref, ncycles_ref_pre, ndrain, \ (double)last_ctick / cf->stable->target_pfreq, ndrain); } #endif alarm_tick = 0; if (last_tick_time == 0 || last_tick_time > tp[1]) { last_tick_time = tp[1]; } else if (last_tick_time + (double)TIMETICK < tp[1]) { alarm_tick = 1; last_tick_time = tp[1]; } if (alarm_tick || (ncycles_ref % 7) == 0) { rtp_only = 0; } else { rtp_only = 1; } pthread_mutex_lock(&cf->sessinfo.lock); if (cf->sessinfo.nsessions > 0) { if (rtp_only == 0) { i = poll(cf->sessinfo.pfds_rtcp, cf->sessinfo.nsessions, 0); } i = poll(cf->sessinfo.pfds_rtp, cf->sessinfo.nsessions, 0); pthread_mutex_unlock(&cf->sessinfo.lock); if (i < 0 && errno == EINTR) { rtpp_command_async_wakeup(cf->stable->rtpp_cmd_cf); tp[0] = getdtime(); continue; } } else { pthread_mutex_unlock(&cf->sessinfo.lock); } tp[2] = getdtime(); sender = rtpp_anetio_pick_sender(proc_cf->op); if (rtp_only == 0) { pthread_mutex_lock(&cf->glock); process_rtp(cf, tp[2], alarm_tick, ndrain, sender, rstats); } else { process_rtp_only(cf, tp[2], ndrain, sender, rstats); pthread_mutex_lock(&cf->glock); } if (cf->rtp_nsessions > 0) { process_rtp_servers(cf, tp[2], sender, rstats); } pthread_mutex_unlock(&cf->glock); rtpp_anetio_pump_q(sender); rtpp_command_async_wakeup(cf->stable->rtpp_cmd_cf); tp[3] = getdtime(); flush_rstats(stats_cf, rstats); #if RTPP_DEBUG recfilter_apply(&proc_cf->sleep_time, tp[1] - tp[0]); recfilter_apply(&proc_cf->poll_time, tp[2] - tp[1]); recfilter_apply(&proc_cf->proc_time, tp[3] - tp[2]); #endif tp[0] = tp[3]; #if RTPP_DEBUG if (last_ctick % (unsigned int)cf->stable->target_pfreq == 0 || last_ctick < 1000) { #if 0 rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld eptime %f, CSV: %f,%f,%f", \ last_ctick, tp[3], (double)last_ctick / cf->stable->target_pfreq, tp[3] - tp[1], tp[3]); #endif rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld eptime %f sleep_time %f poll_time %f proc_time %f CSV: %f,%f,%f,%f", \ last_ctick, tp[3], proc_cf->sleep_time.lastval, proc_cf->poll_time.lastval, proc_cf->proc_time.lastval, \ (double)last_ctick / cf->stable->target_pfreq, proc_cf->sleep_time.lastval, proc_cf->poll_time.lastval, proc_cf->proc_time.lastval); } #endif } }
static void rtpp_anetio_sthread(struct sthread_args *args) { int n, nsend, i, send_errno, nretry; struct rtpp_wi *wi, *wis[100]; #if RTPP_DEBUG_timers double tp[3], runtime, sleeptime; long run_n; runtime = sleeptime = 0.0; run_n = 0; tp[0] = getdtime(); #endif for (;;) { nsend = rtpp_queue_get_items(args->out_q, wis, 100, 0); #if RTPP_DEBUG_timers tp[1] = getdtime(); #endif for (i = 0; i < nsend; i++) { wi = wis[i]; if (wi->wi_type == RTPP_WI_TYPE_SGNL) { rtpp_wi_free(wi); goto out; } nretry = 0; do { n = sendto(wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, wi->tolen); send_errno = (n < 0) ? errno : 0; #if RTPP_DEBUG_netio >= 1 if (wi->debug != 0) { char daddr[MAX_AP_STRBUF]; addrport2char_r(wi->sendto, daddr, sizeof(daddr), ':'); if (n < 0) { RTPP_ELOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d", wi->sock, wi->msg, (long long)wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); } else if (n < wi->msg_len) { RTPP_LOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %lld, %d, %p (%s), %d) = %d: short write", wi->sock, wi->msg, (long long)wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); #if RTPP_DEBUG_netio >= 2 } else { RTPP_LOG(wi->log, RTPP_LOG_DBUG, "sendto(%d, %p, %d, %d, %p (%s), %d) = %d", wi->sock, wi->msg, wi->msg_len, wi->flags, wi->sendto, daddr, wi->tolen, n); #endif } } #endif if (n >= 0) { wi->nsend--; } else { /* "EPERM" is Linux thing, yield and retry */ if ((send_errno == EPERM || send_errno == ENOBUFS) && nretry < RTPP_ANETIO_MAX_RETRY) { sched_yield(); nretry++; } else { break; } } } while (wi->nsend > 0); rtpp_wi_free(wi); } #if RTPP_DEBUG_timers sleeptime += tp[1] - tp[0]; tp[0] = getdtime(); runtime += tp[0] - tp[1]; if ((run_n % 10000) == 0) { RTPP_LOG(args->glog, RTPP_LOG_DBUG, "rtpp_anetio_sthread(%p): run %ld aload = %f filtered = %f", \ args, run_n, runtime / (runtime + sleeptime), args->average_load.lastval); } if (runtime + sleeptime > 1.0) { recfilter_apply(&args->average_load, runtime / (runtime + sleeptime)); runtime = sleeptime = 0.0; } run_n += 1; #endif } out: return; }