#include <semaphore.h>
#include <sys/ioctl.h>
#include <net/if.h>
+#include <inttypes.h>
#ifdef WITH_FWP
-#include <fwp_confdefs.h>
-#include <fwp.h>
-#include <fwp_vres.h>
+#include <frsh.h>
#include <ncurses.h>
+#include <fwp_res.h>
#endif
#define MAX_STREAMS 10
char *opt_comment = NULL;
bool some_queue_is_full = false;
-struct timespec reset_timestamp;
+uint64_t reset_timestamp; /* [nsec] */
bool some_contract_not_accepted = false;
#ifndef WITH_FWP
struct sockaddr_in rem_addr;
#else
- fwp_contract_d_t contract_send;
- fwp_contract_d_t contract_resp;
- fwp_endpoint_d_t endpoint;
- fwp_endpoint_d_t resp_endpoint;
- fwp_vres_d_t vres;
+ frsh_send_endpoint_t endpoint;
+ frsh_receive_endpoint_t resp_endpoint;
+ frsh_vres_id_t vres, vres_rcv;
uint16_t resp_port;
struct receiver receiver;
long wc_delay; /* worst-case delay */
#ifdef WITH_FWP
for (i=0; i < nr_streams; i++) {
if (streams[i].receiver.valid) pthread_kill(streams[i].receiver.thread, SIGUSR1);
- if (streams[i].contract_send) fwp_contract_cancel(streams[i].contract_send);
- if (streams[i].contract_resp)fwp_contract_cancel(streams[i].contract_resp);
}
#else
for (i=0; i < AC_NUM; i++) {
real[0]=0;
}
- snprintf(stream_desc, n, "%d: %s %s (%d bytes per %s +-%s, %d packets/s)%s",
+ snprintf(stream_desc, n, "%"PRIdPTR": %s %s (%d bytes per %s +-%s, %d packets/s)%s",
stream-streams, ac_to_text[stream->ac], bandwidth_to_text(buf[0], stream->bandwidth_bps),
stream->packet_size, usec_to_text(buf[1], stream->period_usec),
usec_to_text(buf[2], stream->jitter*stream->period_usec/100),
exit(0);
}
-int create_ac_socket(unsigned int ac)
+int create_ac_socket(intptr_t ac)
{
int sockfd;
unsigned int yes=1, tos;
void reset_statistics()
{
int i;
+ struct timespec ts;
for (i = 0; i < nr_streams; i++) {
pthread_mutex_lock(&streams[i].mutex);
streams[i].sent = 0;
pthread_mutex_unlock(&streams[i].mutex);
}
pthread_mutex_lock(&delay_stats_mutex);
- clock_gettime(CLOCK_REALTIME, &reset_timestamp);
+ clock_gettime(CLOCK_REALTIME, &ts);
+ reset_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
memset(delay_stats, 0, sizeof(delay_stats));
pthread_mutex_unlock(&delay_stats_mutex);
}
#ifndef WITH_FWP
-int recv_packet_native(unsigned ac, struct msg_t *msg)
+int recv_packet_native(intptr_t ac, struct msg_t *msg)
{
int mlen, ret;
fd_set fdset;
#else
int recv_packet_fwp(struct stream *stream, struct msg_t *msg)
{
- int mlen;
- mlen = fwp_recv(stream->resp_endpoint, msg, sizeof(*msg), 0);
+ size_t mlen;
+
+ mlen = frsh_receive_sync(stream->resp_endpoint, msg, sizeof(*msg), &mlen, NULL);
return mlen;
}
#endif
struct msg_t msg;
long long int trans_time_usec, client_to_server_usec, server_to_client_usec;
long long int min_trans_time;
- struct timespec send_timestamp, server_timestamp, recv_timestamp;
- int mlen, ret;
- unsigned ac;
+ struct timespec ts;
+ uint64_t send_timestamp, server_timestamp, recv_timestamp;
+ int mlen;
+ intptr_t ac;
min_trans_time = ~0;
ac = stream->ac;
mlen = recv_packet_fwp(stream, &msg);
#else
- ac = (unsigned)arg;
+ ac = (intptr_t)arg;
mlen = recv_packet_native(ac, &msg);
#endif
if (mlen < 0) {
- error(0, errno, "receive_packet error");
+ if (errno != EINTR)
+ error(0, errno, "receive_packet error");
goto out;
}
- clock_gettime(CLOCK_REALTIME,&recv_timestamp);
+ clock_gettime(CLOCK_REALTIME,&ts);
+ recv_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
send_timestamp = msg.send_timestamp;
server_timestamp = msg.sendback_timestamp;
/* Check whether this message was sent after reset_statistics() */
- if ((ret = timespec_sub_usec(&send_timestamp, &reset_timestamp)) < 0) {
+ if (send_timestamp < reset_timestamp) {
continue; /* If so, don't count it */
}
- trans_time_usec = timespec_sub_usec(&recv_timestamp ,&send_timestamp) / 2;
- client_to_server_usec = timespec_sub_usec(&server_timestamp, &send_timestamp);
- server_to_client_usec = timespec_sub_usec(&recv_timestamp, &server_timestamp);
+ trans_time_usec = (recv_timestamp - send_timestamp) / 2 / 1000;
+ client_to_server_usec = (server_timestamp - send_timestamp) / 1000;
+ server_to_client_usec = (recv_timestamp - server_timestamp) / 1000;
pthread_mutex_lock(&delay_stats_mutex);
if (trans_time_usec < MAX_DELAY_US && trans_time_usec >= 0) {
int ret;
buff->msg.resp_port = htons(stream->resp_port);
- ret = fwp_send(stream->endpoint, buff, stream->packet_size, 0);
-
- return ret;
+ ret = frsh_send_sync(stream->endpoint, buff, stream->packet_size);
+
+ return (ret == 0) ? 0 : -1;
}
#endif
union msg_buff buff;
unsigned long int seqn;
struct stream* stream = (struct stream*) arg;
+ struct timespec ts;
int ret;
#ifndef WITH_FWP
/* buff.msg.tos = ac_to_tos[stream->ac]; */
buff.msg.stream = stream-streams;
- clock_gettime(CLOCK_REALTIME,&buff.msg.send_timestamp);
+ clock_gettime(CLOCK_REALTIME,&ts);
+ buff.msg.send_timestamp = ts.tv_sec*1000000000LL + ts.tv_nsec;
ret = send_packet(stream, &buff);
if (ret < 0) {
fflush(stdout);
#endif
- wait_for_next_send(stream, &buff.msg.send_timestamp);
+ wait_for_next_send(stream, &ts);
}
out:
sem_post(&sem_thread_finished);
#ifdef WITH_FWP
static int negotiate_contract_for_stream_fwp(struct stream *stream)
{
- fwp_contract_t contract;
- fwp_vres_d_t vres2;
+ frsh_contract_t contract;
int ret;
+ frsh_rel_time_t budget, period, deadline;
+ frsh_signal_info_t si;
/* Contract for client->server stream */
- memset(&contract, 0, sizeof(contract));
- contract.budget = stream->packet_size;
- contract.period_usec = stream->period_usec;
- contract.deadline_usec = 3*stream->period_usec;
+ frsh_contract_init(&contract);
+ frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+ period = frsh_usec_to_rel_time(stream->period_usec);
+ frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_REGULAR);
+ deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+ frsh_contract_set_timing_reqs(&contract, false, &deadline, 0, si, 0, si);
- stream->contract_send = fwp_contract_create(&contract);
- ret = fwp_contract_negotiate(stream->contract_send, &stream->vres);
+ ret = frsh_contract_negotiate(&contract, &stream->vres);
+ frsh_contract_destroy(&contract);
if (ret != 0) {
- stream->contract_send = NULL;
-/* fprintf(stderr, "Send contract was not accepted\n\n\n"); */
+ stream->vres = NULL;
+ fprintf(stderr, "Send contract was not accepted\n");
return ret;
}
/* Contract for server->client stream */
- memset(&contract, 0, sizeof(contract));
- contract.budget = stream->packet_size;
- contract.period_usec = stream->period_usec;
- contract.deadline_usec = 3*stream->period_usec;
-
- stream->contract_resp = fwp_contract_create(&contract);
- ret = fwp_contract_negotiate(stream->contract_resp, &vres2);
+ /* TODO: Use group negotiation for these two contracts */
+ frsh_contract_init(&contract);
+ frsh_contract_set_resource_and_label(&contract, FRSH_RT_NETWORK, FRSH_NETPF_FWP, NULL);
+ frsh_network_bytes_to_budget(FRSH_NETPF_FWP, stream->packet_size, &budget);
+ period = frsh_usec_to_rel_time(stream->period_usec);
+ frsh_contract_set_basic_params(&contract, &budget, &period, FRSH_WT_BOUNDED, FRSH_CT_DUMMY);
+ deadline = frsh_usec_to_rel_time(3*stream->period_usec);
+ frsh_contract_set_timing_reqs(&contract, false, &deadline, 0, si, 0, si);
+
+ ret = frsh_contract_negotiate(&contract, &stream->vres_rcv);
+ frsh_contract_destroy(&contract);
if (ret != 0) {
- stream->contract_resp = NULL;
-/* fprintf(stderr, "Receive contract was not accepted\n\n\n"); */
+ fprintf(stderr, "Receive contract was not accepted\n");
return ret;
}
/* fwp_endpoint_attr_t attr; */
int ret;
struct hostent* ph;
+ frsh_contract_t c;
+ fres_block_fwp_sched *fwp_sched;
- stream->ac = fwp_vres_get_ac(stream->vres);
+ frsh_vres_get_contract(stream->vres, &c);
+ fwp_sched = fres_contract_get_fwp_sched(c);
+
+ stream->ac = fwp_sched->ac_id;
/* fwp_endpoint_attr_init(&attr); */
/* fwp_endpoint_attr_setreliability(&attr, FWP_EPOINT_BESTEFFORT); */
ph = gethostbyname(server_addr);
if (ph && ph->h_addr_list[0]) {
struct in_addr *a = (struct in_addr *)(ph->h_addr_list[0]);
- ret = fwp_send_endpoint_create(a->s_addr, BASE_PORT + stream->ac,
- NULL, &stream->endpoint);
- /* stream->rem_addr.sin_port = htons(BASE_PORT + stream->ac); */
- if (ret < 0) error(1, errno, "fwp_send_endpoint_create");
-
- ret = fwp_send_endpoint_bind(stream->endpoint, stream->vres);
- if (ret != 0) error(1, errno, "fwp_send_endpoint_bind");
+ frsh_send_endpoint_protocol_info_t spi = { NULL, 0 };
+ frsh_receive_endpoint_protocol_info_t rpi = { NULL, 0 };
+ frsh_endpoint_queueing_info_t qi = { .queue_size=0, .queue_policy=FRSH_QRP_OLDEST };
+ ret = frsh_send_endpoint_create(FRSH_NETPF_FWP, a->s_addr, BASE_PORT + stream->ac,
+ spi, &stream->endpoint);
+ if (ret < 0) error(1, errno, "frsh_send_endpoint_create()");
- ret = fwp_receive_endpoint_create(0, NULL, &stream->resp_endpoint);
+ ret = frsh_send_endpoint_bind(stream->vres, stream->endpoint);
+ if (ret != 0) error(1, errno, "frsh_send_endpoint_bind");
+
+ ret = frsh_receive_endpoint_create(FRSH_NETPF_FWP, 0, qi, rpi,
+ &stream->resp_endpoint);
if (ret != 0) error(1, errno, "fwp_receive_endpoint_create");
unsigned int port;
- fwp_endpoint_get_params(stream->resp_endpoint, NULL, &port, NULL);
+ frsh_receive_endpoint_get_params(stream->resp_endpoint, NULL, &port, NULL, NULL);
stream->resp_port = port;
ret = pthread_create(&stream->receiver.thread, NULL, receiver, (void*)stream);
}
if (packet_size < sizeof(struct msg_t)) {
- error(1, 0, "Packet size too small (min %d)", sizeof(struct msg_t));
+ error(1, 0, "Packet size too small (min %zd)", sizeof(struct msg_t));
}
stream->packet_size = packet_size;
fprintf(stderr, " -C comment (added to header)\n");
fprintf(stderr, " -c count (number of seconds to run)\n");
fprintf(stderr, " -g histogram granularity [usec]\n");
- fprintf(stderr, " -I <interface> send packets from this interface");
+ fprintf(stderr, " -I <interface> send packets from this interface\n");
fprintf(stderr, " -j send jitter (0-100) [%%]\n");
fprintf(stderr, " -o output filename (.dat will be appended)\n");
fprintf(stderr, " -q gather statistics only after some queue becomes full\n");
reset_statistics();
#ifdef WITH_FWP
- rc = fwp_init();
+ rc = frsh_init();
if (rc != 0) {
error(1, errno, "FWP initialization failed");
}
#else
- int ac;
+ intptr_t ac;
/* create four receivers each per AC */
for (ac = AC_NUM - 1; ac >= 0; ac--) {
ac_sockfd[ac] = create_ac_socket(ac);
seconds = 1;
frames=0;
while (!exit_flag) {
+#ifdef WITH_FWP
usleep(40000);
+#else
+ sleep(1);
+#endif
frames++;
if (frames>=25) {
seconds++;
#ifdef WITH_FWP
//endwin();
- fwp_done();
+ for (i=0; i < nr_streams; i++) {
+ if (streams[i].vres)
+ frsh_contract_cancel(streams[i].vres);
+ if (streams[i].vres_rcv)
+ frsh_contract_cancel(streams[i].vres_rcv);
+ }
#else
fprintf(stderr, "\nWaiting for threads to finish\n");
wait_for_all_threads_to_finish();
- struct timespec end_timestamp, measure_length;
- clock_gettime(CLOCK_REALTIME,&end_timestamp);
- timespec_sub(&measure_length, &end_timestamp, &reset_timestamp);
+ struct timespec ts;
+ uint64_t end_timestamp, measure_length;
+ clock_gettime(CLOCK_REALTIME,&ts);
+ end_timestamp = ts.tv_sec*1000000000LL+ts.tv_nsec;
+ measure_length = end_timestamp - reset_timestamp;
- save_results(argc, argv, timespec2usec(&measure_length));
+ save_results(argc, argv, measure_length/1000);
#endif
return 0;