static double compute_loss_event(struct tfrc *state) { int i; uint32_t t, temp, I_tot0 = 0, I_tot1 = 0, I_tot = 0; struct timeval now; double I_mean, p; if (state->ii < N) { return 0; } for (i = state->ii - N; i < state->ii; i++) { temp = loss[i + 1].seq - loss[i].seq; I_tot0 = I_tot0 + temp * state->weight[i]; if (i >= (state->ii - N + 1)) { I_tot1 = I_tot1 + temp * state->weight[i - 1]; } } I_tot1 = I_tot1 + (arrival[state->jj].seq - loss[state->ii].seq) * state->weight[N - 1]; I_tot = (I_tot1 > I_tot0) ? I_tot1 : I_tot0; I_mean = I_tot / state->W_tot; p = 1 / I_mean; gettimeofday(&now, NULL); t = tv_diff_usec(now, state->start_time); return p; }
struct audio_frame *audio_cap_testcard_read(void *state) { struct state_audio_capture_testcard *s; s = (struct state_audio_capture_testcard *) state; struct timeval curr_time; gettimeofday(&curr_time, NULL); if(tv_gt(s->next_audio_time, curr_time)) { usleep(tv_diff_usec(s->next_audio_time, curr_time)); } else { // we missed more than 2 "frame times", in that case, just drop the packages if (tv_diff_usec(curr_time, s->next_audio_time) > 2 * (1000 * 1000 * CHUNK / 48000)) { s->next_audio_time = curr_time; fprintf(stderr, MODULE_NAME "Warning: skipping some samples (late grab call).\n"); } } tv_add_usec(&s->next_audio_time, 1000 * 1000 * CHUNK / 48000); if(s->current_sample == TONE) { s->audio.data = (char* )(s->audio_tone + s->samples_played * AUDIO_CHANNELS); // it is short so _not_ (* 2) } else { s->audio.data = (char *)(s->audio_silence + s->samples_played * AUDIO_CHANNELS); } s->samples_played += CHUNK; if(s->samples_played >= AUDIO_SAMPLE_RATE) { s->samples_played = 0; if(s->current_sample == TONE) { s->current_sample = SILENCE; } else { s->current_sample = TONE; } } return &s->audio; }
uint32_t get_local_mediatime_us(void) { static struct timeval start_time; static uint32_t random_offset; static int first = 0; struct timeval curr_time; if (first == 0) { gettimeofday(&start_time, NULL); random_offset = lbl_random(); first = 1; } gettimeofday(&curr_time, NULL); return (tv_diff_usec(curr_time, start_time)) + random_offset; }
/* * segment_touch() - "touch" [read or write] each page of specified range * -- from offset to offset+length -- to fault in or to * test protection. * NOTE: offset is relative to start of mapping, not start of file! */ int segment_touch(char *name, range_t *range, int rw) { glctx_t *gcp = &glctx; segment_t *segp; off_t offset; size_t length, maxlength; unsigned long *memp; struct timeval t_start, t_end; segp = segment_get(name); if (segp == NULL) { fprintf(stderr, "%s: no such segment: %s\n", gcp->program_name, name); return SEG_ERR; } offset = round_down_to_pagesize(range->offset); if (offset >= segp->seg_length) { fprintf(stderr, "%s: offset %ld is past end of segment %s\n", gcp->program_name, offset, name); return SEG_ERR; } memp = (unsigned long*)(segp->seg_start + offset); maxlength = segp->seg_length - offset; length = range->length; if (length) length = round_up_to_pagesize(length); /* * note: we silently truncate to max length [end of segment] */ if (length == 0 || length > maxlength) length = maxlength; gettimeofday(&t_start, NULL); touch_memory(rw, memp, length); gettimeofday(&t_end, NULL); printf("%s: touched %d pages in %6.3f secs\n", gcp->program_name, length/gcp->pagesize, (float)(tv_diff_usec(&t_start, &t_end))/1000000.0); return SEG_OK; }
/* * migrate <to-node-id[s]> [<from-node-id[s]>] * * Node id[s] - single node id or comma-separated list * <to-node-id[s]> - 1-for-1 with <from-node-id[s]>, OR * if <from-node-id[s]> omitted, <to-node-id[s]> must be * a single node id. */ static int migrate_process(char *args) { glctx_t *gcp = &glctx; unsigned int *fromids, *toids; char *idlist, *nextarg; struct timeval t_start, t_end; int nr_to, nr_from; int nr_migrated; int ret = CMD_ERROR; if (!numa_supported()) return CMD_ERROR; toids = calloc(gcp->numa_max_node, sizeof(*toids)); fromids = calloc(gcp->numa_max_node, sizeof(*fromids)); /* * <to-node-id[s]> */ if (!required_arg(args, "<to-node-id[s]>")) return CMD_ERROR; idlist = strtok_r(args, whitespace, &nextarg); nr_to = get_arg_nodeid_list(idlist, toids); if (nr_to <= 0) goto out_free; args = nextarg + strspn(nextarg, whitespace); if (*args != '\0') { /* * apparently, <from-node-id[s]> present */ idlist = strtok_r(args, whitespace, &nextarg); nr_from = get_arg_nodeid_list(idlist, fromids); if (nr_from <= 0) goto out_free; if (nr_from != nr_to) { fprintf(stderr, "%s: # of 'from' ids must = # of 'to' ids\n", gcp->program_name); goto out_free; } } else { int i; /* * no <from-node-id[s]>, nr_to must == 1, * get fromids from memory policy. */ if (nr_to > 1) { fprintf(stderr, "%s: # to ids must = 1" " when no 'from' ids specified\n", gcp->program_name); goto out_free; } nr_from = get_current_nodeid_list(fromids); if (nr_from <= 0) goto out_free; /* * remove 'to' node from 'from' list. to and from * lists can't intersect. */ for (i = nr_from - 1; i >= 0; --i) { if (*toids == *(fromids + i)) { while (i <= nr_from) { *(fromids + i) = *(fromids + i + 1); ++i; } --nr_from; break; } } /* * fill out nr_from toids with the single 'to' node */ for (; nr_to < nr_from; ++nr_to) *(toids + nr_to) = *toids; /* toids[0] */ } gettimeofday(&t_start, NULL); nr_migrated = syscall(__NR_migrate_pages, getpid(), nr_from, fromids, toids); if (nr_migrated < 0) { int err = errno; fprintf(stderr, "%s: migrate_pages failed - %s\n", gcp->program_name, strerror(err)); goto out_free; } gettimeofday(&t_end, NULL); printf("%s: migrated %d pages in %6.3fsecs\n", gcp->program_name, nr_migrated, (float)(tv_diff_usec(&t_start, &t_end)) / 1000000.0); ret = CMD_SUCCESS; out_free: free(toids); free(fromids); return ret; }
static void save_arrival(struct tfrc *state, struct timeval curr_time, uint16_t seq) { int kk, inc, last_jj; uint16_t udelta; uint32_t now; uint32_t ext_seq; static uint16_t last_seq; static uint32_t ext_last_ack; static int last_ack_jj = 0; gettimeofday(&curr_time, NULL); now = tv_diff_usec(curr_time, state->start_time); if (state->jj == -1) { /* first packet arrival */ state->jj = 0; last_seq = seq; ext_last_ack = seq; last_ack_jj = 0; arrival[state->jj].seq = seq; arrival[state->jj].ts = now; return; } udelta = seq - last_seq; state->total_pckts++; if (udelta < MAX_DROPOUT) { /* in order, with permissible gap */ if (seq < last_seq) { state->cycles++; } /* record arrival */ last_jj = state->jj; state->jj = (state->jj + udelta) % MAX_HISTORY; set_zero(last_jj, state->jj, udelta); ext_seq = seq + state->cycles * RTP_SEQ_MOD; last_seq = seq; arrival[state->jj].seq = ext_seq; arrival[state->jj].ts = now; if (udelta < 10) state->gap[udelta - 1]++; if ((ext_seq - ext_last_ack) == 1) { /* We got two consecutive packets, no loss */ ext_last_ack = ext_seq; last_ack_jj = state->jj; } else { /* Sequence number jumped, we've missed a packet for some reason */ if (arrived(last_ack_jj, state->jj) >= 4) { record_loss(state, ext_last_ack, ext_seq, arrival[last_ack_jj].ts, now); ext_last_ack = ext_seq; last_ack_jj = state->jj; } } } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) { printf(" -- seq:%u last seq:%u ", seq, arrival[state->jj].seq); abort(); /* FIXME */ } else { /* duplicate or reordered packet */ ext_seq = seq + state->cycles * RTP_SEQ_MOD; state->ooo++; if (ext_seq > ext_last_ack) { inc = ext_seq - arrival[state->jj].seq; kk = (state->jj + inc) % MAX_HISTORY; if (arrival[kk].seq == 0) { arrival[kk].seq = ext_seq; arrival[kk].ts = (arrival[last_ack_jj].ts + now) / 2; /* NOT the best interpolation */ } while (arrival[last_ack_jj + 1].seq != 0 && last_ack_jj < state->jj) { last_ack_jj = (last_ack_jj + 1) % MAX_HISTORY; } ext_last_ack = arrival[last_ack_jj].seq; } } }
/*------------------------------------------------------------------------ * void client_handler(ttp_session_t *session); * * This routine is run by the client processes that are created in * response to incoming connections. *------------------------------------------------------------------------*/ void client_handler(ttp_session_t *session) { retransmission_t retransmission; /* the retransmission data object */ struct timeval start, stop; /* the start and stop times for the transfer */ struct timeval prevpacketT; /* the send time of the previous packet */ struct timeval currpacketT; /* the interpacket delay value */ struct timeval lastfeedback; /* the time since last client feedback */ struct timeval lasthblostreport; /* the time since last 'heartbeat lost' report */ u_int32_t deadconnection_counter; /* the counter for checking dead conn timeout */ int retransmitlen; /* number of bytes read from retransmission queue */ u_char datagram[MAX_BLOCK_SIZE + 6]; /* the datagram containing the file block */ int64_t ipd_time; /* the time to delay/sleep after packet, signed */ int64_t ipd_usleep_diff; /* the time correction to ipd_time, signed */ int64_t ipd_time_max; int status; ttp_transfer_t *xfer = &session->transfer; ttp_parameter_t *param = session->parameter; u_int64_t delta; u_char block_type; /* negotiate the connection parameters */ status = ttp_negotiate(session); if (status < 0) error("Protocol revision number mismatch"); /* have the client try to authenticate to us */ status = ttp_authenticate(session, session->parameter->secret); if (status < 0) error("Client authentication failure"); if (1==param->verbose_yn) { fprintf(stderr,"Client authenticated. Negotiated parameters are:\n"); fprintf(stderr,"Block size: %d\n", param->block_size); fprintf(stderr,"Buffer size: %d\n", param->udp_buffer); fprintf(stderr,"Port: %d\n", param->tcp_port); } /* while we haven't been told to stop */ while (1) { /* make the client descriptor blocking */ status = fcntl(session->client_fd, F_SETFL, 0); if (status < 0) error("Could not make client socket blocking"); /* negotiate another transfer */ status = ttp_open_transfer(session); if (status < 0) { warn("Invalid file request"); continue; } /* negotiate a data transfer port */ status = ttp_open_port(session); if (status < 0) { warn("UDP socket creation failed"); continue; } /* make the client descriptor non-blocking again */ status = fcntl(session->client_fd, F_SETFL, O_NONBLOCK); if (status < 0) error("Could not make client socket non-blocking"); /*--------------------------- * START TIMING *---------------------------*/ gettimeofday(&start, NULL); if (param->transcript_yn) xscript_data_start(session, &start); lasthblostreport = start; lastfeedback = start; prevpacketT = start; deadconnection_counter = 0; ipd_time = 0; ipd_time_max = 0; ipd_usleep_diff = 0; retransmitlen = 0; /* start by blasting out every block */ xfer->block = 0; while (xfer->block <= param->block_count) { /* default: flag as retransmitted block */ block_type = TS_BLOCK_RETRANSMISSION; /* precalculate time to wait after sending the next packet */ gettimeofday(&currpacketT, NULL); ipd_usleep_diff = xfer->ipd_current + tv_diff_usec(prevpacketT, currpacketT); prevpacketT = currpacketT; if (ipd_usleep_diff > 0 || ipd_time > 0) { ipd_time += ipd_usleep_diff; } ipd_time_max = (ipd_time > ipd_time_max) ? ipd_time : ipd_time_max; /* see if transmit requests are available */ status = read(session->client_fd, ((char*)&retransmission)+retransmitlen, sizeof(retransmission)-retransmitlen); #ifndef VSIB_REALTIME if ((status <= 0) && (errno != EAGAIN)) error("Retransmission read failed"); #else if ((status <= 0) && (errno != EAGAIN) && (!session->parameter->fileout)) error("Retransmission read failed and not writing local backup file"); #endif if (status > 0) retransmitlen += status; /* if we have a retransmission */ if (retransmitlen == sizeof(retransmission_t)) { /* store current time */ lastfeedback = currpacketT; lasthblostreport = currpacketT; deadconnection_counter = 0; /* if it's a stop request, go back to waiting for a filename */ if (ntohs(retransmission.request_type) == REQUEST_STOP) { fprintf(stderr, "Transmission complete.\n"); break; } /* otherwise, handle the retransmission */ status = ttp_accept_retransmit(session, &retransmission, datagram); if (status < 0) warn("Retransmission error"); retransmitlen = 0; /* if we have no retransmission */ } else if (retransmitlen < sizeof(retransmission_t)) { /* build the block */ xfer->block = min(xfer->block + 1, param->block_count); block_type = (xfer->block == param->block_count) ? TS_BLOCK_TERMINATE : TS_BLOCK_ORIGINAL; status = build_datagram(session, xfer->block, block_type, datagram); if (status < 0) { sprintf(g_error, "Could not read block #%u", xfer->block); error(g_error); } /* transmit the block */ status = sendto(xfer->udp_fd, datagram, 6 + param->block_size, 0, xfer->udp_address, xfer->udp_length); if (status < 0) { sprintf(g_error, "Could not transmit block #%u", xfer->block); warn(g_error); continue; } /* if we have too long retransmission message */ } else if (retransmitlen > sizeof(retransmission_t)) { fprintf(stderr, "warn: retransmitlen > %d\n", (int)sizeof(retransmission_t)); retransmitlen = 0; } /* monitor client heartbeat and disconnect dead client */ if ((deadconnection_counter++) > 2048) { char stats_line[160]; deadconnection_counter = 0; /* limit 'heartbeat lost' reports to 500ms intervals */ if (get_usec_since(&lasthblostreport) < 500000.0) continue; gettimeofday(&lasthblostreport, NULL); /* throttle IPD with fake 100% loss report */ #ifndef VSIB_REALTIME retransmission.request_type = htons(REQUEST_ERROR_RATE); retransmission.error_rate = htonl(100000); retransmission.block = 0; ttp_accept_retransmit(session, &retransmission, datagram); #endif delta = get_usec_since(&lastfeedback); /* show an (additional) statistics line */ snprintf(stats_line, sizeof(stats_line)-1, " n/a n/a n/a %7u %6.2f %3u -- no heartbeat since %3.2fs\n", xfer->block, 100.0 * xfer->block / param->block_count, session->session_id, 1e-6*delta); if (param->transcript_yn) xscript_data_log(session, stats_line); fprintf(stderr, "%s", stats_line); /* handle timeout for normal file transfers */ #ifndef VSIB_REALTIME if ((1e-6 * delta) > param->hb_timeout) { fprintf(stderr, "Heartbeat timeout of %d seconds reached, terminating transfer.\n", param->hb_timeout); break; } #else /* handle timeout condition for : realtime with local backup, simple realtime */ if ((1e-6 * delta) > param->hb_timeout) { if ((session->parameter->fileout) && (block_type == TS_BLOCK_TERMINATE)) { fprintf(stderr, "Reached the Terminate block and timed out, terminating transfer.\n"); break; } else if(!session->parameter->fileout) { fprintf(stderr, "Heartbeat timeout of %d seconds reached and not doing local backup, terminating transfer now.\n", param->hb_timeout); break; } else { lastfeedback = currpacketT; } } #endif } /* wait before handling the next packet */ if (block_type == TS_BLOCK_TERMINATE) { usleep_that_works(10*ipd_time_max); } if (ipd_time > 0) { usleep_that_works(ipd_time); } } /*--------------------------- * STOP TIMING *---------------------------*/ gettimeofday(&stop, NULL); if (param->transcript_yn) xscript_data_stop(session, &stop); delta = 1000000LL * (stop.tv_sec - start.tv_sec) + stop.tv_usec - start.tv_usec; /* report on the transfer */ if (param->verbose_yn) fprintf(stderr, "Server %d transferred %llu bytes in %0.2f seconds (%0.1f Mbps)\n", session->session_id, (ull_t)param->file_size, delta / 1000000.0, 8.0 * param->file_size / (delta * 1e-6 * 1024*1024) ); /* close the transcript */ if (param->transcript_yn) xscript_close(session, delta); #ifndef VSIB_REALTIME /* close the file */ fclose(xfer->file); #else /* VSIB local disk copy: close file only if file output was requested */ if (param->fileout) { fclose(xfer->file); } /* stop the VSIB */ stop_vsib(session); fclose(xfer->vsib); #endif /* close the UDP socket */ close(xfer->udp_fd); memset(xfer, 0, sizeof(*xfer)); } //while(1) }