Commit 59fe6d48 authored by Andreas Schmidt's avatar Andreas Schmidt

Add retransmissions.

parent 21f9500b
Pipeline #2694 passed with stages
in 1 minute and 37 seconds
......@@ -89,9 +89,16 @@ local ex_type = Field.new("prrt.type")
local function getType() return ex_type()() end
local function getTypeName() return prrtPacketTypeNames[getType()] end
local ex_index = Field.new("prrt.index")
local function getIndex() return ex_index()() end
local ex_data_length = Field.new("prrt.data.length")
local function getDataLength() return ex_data_length()() end
local ex_red_baseseqno = Field.new("prrt.redundancy.baseSequenceNumber")
local function getRedBaseSeqNo() return ex_red_baseseqno()() end
local ex_red_n = Field.new("prrt.redundancy.n")
local function getRedN() return ex_red_n()() end
......@@ -109,7 +116,7 @@ local function dissect_data(buffer, pinfo, root)
tree:add(pf_data_groupRTprop, buffer:range(8,4))
tree:add(pf_data_packettimeout, buffer:range(12,4))
local label = "DATA Len=" .. getDataLength()
local label = "[D] Idx=" .. getIndex() .. " Len=" .. getDataLength()
tree:set_text(label)
pinfo.cols.info:set(label)
end
......@@ -121,7 +128,7 @@ local function dissect_redundancy(buffer, pinfo, root)
tree:add(pf_red_n, buffer:range(6,1))
tree:add(pf_red_k, buffer:range(7,1))
local label = "REDUNDANCY n=" .. getRedN() .. " k=" .. getRedK()
local label = "[R] Idx=" .. getIndex() .. " b=" .. getRedBaseSeqNo() .. " n=" .. getRedN() .. " k=" .. getRedK()
tree:set_text(label)
pinfo.cols.info:set(label)
end
......@@ -139,7 +146,7 @@ local function dissect_feedback(buffer, pinfo, root)
tree:add(pf_fb_acktype, buffer:range(20,1))
tree:add(pf_fb_ackSeqN, buffer:range(21, 2))
local label = "FEEDBACK"
local label = "[F]"
tree:set_text(label)
pinfo.cols.info:set(label)
end
......
......@@ -3,10 +3,7 @@ set (PRRT_SOURCES ../defines.h
clock.c clock.h
receiver.c receiver.h
socket.c socket.h
types/applicationConstraints.c types/applicationConstraints.h
types/block.c types/block.h
types/codingParams.c types/codingParams.h
types/channelStateInformation.c types/channelStateInformation.h
timer.c timer.h
processes/dataReceiver.c processes/dataReceiver.h
processes/dataTransmitter.c processes/dataTransmitter.h
stores/dataPacketStore.c stores/dataPacketStore.h
......@@ -16,9 +13,13 @@ set (PRRT_SOURCES ../defines.h
stores/packetDeliveryStore.c stores/packetDeliveryStore.h
stores/receptionTable.c stores/receptionTable.h
stores/repairBlockStore.c stores/repairBlockStore.h
types/packetTimeout.c types/packetTimeout.h
types/applicationConstraints.c types/applicationConstraints.h
types/block.c types/block.h
types/codingParams.c types/codingParams.h
types/channelStateInformation.c types/channelStateInformation.h
types/lossStatistics.c types/lossStatistics.h
types/packet.c types/packet.h
types/packetTimeout.c types/packetTimeout.h
vdmcode/block_code.c vdmcode/block_code.h types/packetTracking.c types/packetTracking.h types/rateSample.c types/rateSample.h)
if (XLAP)
......
......@@ -6,9 +6,9 @@
prrtByteCount_t BBR_Inflight(BBR* bbr, double gain)
{
if (bbr->rtprop == Inf)
if (bbr->rtprop == RTprop_Inf)
return bbr->initial_cwnd; /* no valid RTT samples yet */
uint32_t quanta = 0;
uint32_t quanta = bbr->mps;
uint32_t estimated_bdp = (uint32_t) round((((double)bbr->bw) * bbr->rtprop) / (1000 * 1000));
return (uint32_t)(gain * estimated_bdp + quanta);
}
......@@ -188,13 +188,18 @@ void BBR_ModulateCwndForProbeRTT(BBR* bbr)
void BBR_ModulateCwndForRecovery(BBR* bbr, prrtByteCount_t bytes_lost, prrtByteCount_t pipe, prrtByteCount_t delivered)
{
if (bytes_lost > 0)
bbr->cwnd = MAX(bbr->cwnd - bytes_lost, bbr->mps);
if (bytes_lost > 0) {
if (bbr->cwnd > bytes_lost) {
bbr->cwnd = MAX(bbr->cwnd - bytes_lost, bbr->mps);
} else {
bbr->cwnd = bbr->mps;
}
}
if (bbr->packet_conservation)
bbr->cwnd = MAX(bbr->cwnd, pipe + delivered);
}
void BBR_SetCwnd(BBR* bbr, PrrtPacketTracking* packetTracking)
{
BBR_UpdateTargetCwnd(bbr);
......@@ -213,7 +218,7 @@ void BBR_SetCwnd(BBR* bbr, PrrtPacketTracking* packetTracking)
void BBR_SetPacingRateWithGain(BBR* bbr, double pacing_gain)
{
double rate = (pacing_gain * ((double)bbr->bw));
debug(DEBUG_BBR, "Current rate: %u, Pacing gain: %f, BtlBw: %u, Calc Rate: %u, Filled pipe: %u", bbr->pacing_rate,
debug(DEBUG_BBR, "Current rate: %f, Pacing gain: %f, BtlBw: %u, Calc Rate: %f, Filled pipe: %u", bbr->pacing_rate,
pacing_gain, bbr->bw, rate, bbr->filled_pipe);
if (rate != 0 && (bbr->filled_pipe || rate > bbr->pacing_rate))
bbr->pacing_rate = rate;
......@@ -306,7 +311,7 @@ BBR* BBR_Init(prrtByteCount_t maximum_payload_size)
bbr->initial_cwnd = 4 * maximum_payload_size;
bbr->has_seen_rtt = false;
bbr->btlBwFilter = WindowedFilter_create(true, 10);
bbr->rtprop = Inf;
bbr->rtprop = RTprop_Inf;
bbr->rtprop_stamp = PrrtClock_get_current_time_us();
bbr->probe_rtt_done_stamp = 0;
bbr->probe_rtt_round_done = false;
......
......@@ -16,7 +16,7 @@
#define BBRHighGain ((((float)2885) / 1000) + 1)
#define BBRGainCycleLen 8
#define ProbeRTTDuration 200000 //200ms
#define Inf UINT32_MAX
#define RTprop_Inf UINT32_MAX
enum bbr_state {
STARTUP,
......
This diff is collapsed.
......@@ -2,11 +2,13 @@
#include <netdb.h>
#include <string.h>
#include "../../defines.h"
#include "../timer.h"
#include "../receiver.h"
#include "../socket.h"
#include "../types/block.h"
#include "../../util/dbg.h"
#include "../../util/common.h"
#include "../../util/time.h"
#include "dataTransmitter.h"
#include <math.h>
......@@ -79,22 +81,23 @@ static bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet) {
memset(buf, 0, sizeof(buf));
prrtPacketLength_t length = PrrtPacket_size(packet);
prrtPacketLength_t payloadLength = packet->payloadLength;
bool paceSuccessful = PrrtSocket_pace(sock_ptr);
if (!paceSuccessful) {
debug(DEBUG_DATATRANSMITTER, "Pacing interrupted.");
PrrtPacket_destroy(packet);
return false;
}
debug(DEBUG_DATATRANSMITTER, "Pacing interval passed.");
int64_t space = PrrtReceiver_get_space(sock_ptr->receiver);
while (space < sock_ptr->maximum_payload_size) {
//PrrtReceiver_check_rto(sock_ptr->receiver, packet->sequenceNumber, PrrtPacket_type(packet));
PrrtReceiver_wait_for_space(sock_ptr->receiver);
if(PrrtSocket_closing(sock_ptr)) {
PrrtPacket_destroy(packet);
return false;
}
space = PrrtReceiver_get_space(sock_ptr->receiver);
bool waitSuccessful = PrrtReceiver_wait_for_space(sock_ptr->receiver, sock_ptr->maximum_payload_size,
sock_ptr->applicationConstraints);
if(!waitSuccessful) {
debug(DEBUG_DATATRANSMITTER, "Wait for space interrupted.");
PrrtPacket_destroy(packet);
return false;
}
debug(DEBUG_DATATRANSMITTER, "Space available.");
prrtTimestamp_t now = PrrtClock_get_current_time_us();
if (sock_ptr->pacingEnabled) {
......@@ -160,11 +163,59 @@ static bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet) {
return false;
}
typedef struct timer_arg {
PrrtSocket* socket;
PrrtBlock* block;
} RetransmissionTimerArgs;
void retransmission_round_handler(void *arg) {
uint8_t j;
RetransmissionTimerArgs* args = (RetransmissionTimerArgs*) arg;
PrrtBlock *block = args->block;
PrrtSocket *socket = args->socket;
if(block->inRound > 0) {
PrrtReceiver_rto_check(socket->receiver, socket->applicationConstraints);
}
if (PrrtSocket_closing(socket) || block->inRound >= block->codingParams->c) {
PrrtBlock_destroy(block);
free(arg);
return;
}
uint32_t redundancyPackets = block->codingParams->n_cycle[block->inRound];
for (j = 0; j < redundancyPackets; j++) {
PrrtPacket *red_pkt = PrrtBlock_get_first_red_data(block);
bool sendResult = send_packet(socket, red_pkt);
if(!sendResult) {
debug(DEBUG_DATATRANSMITTER, "Sending redundancy data failed.");
PrrtBlock_destroy(block);
free(arg);
return;
}
}
block->inRound++;
PrrtTimerTask task = {
.arg = arg,
.fun = retransmission_round_handler
};
uint32_t waittime_us = PrrtReceiver_get_retransmission_delay(socket->receiver, socket->applicationConstraints);
prrtTimerDate deadline = abstime_from_now(waittime_us);
debug(DEBUG_DATATRANSMITTER, "Set timer to expire in: %dus", waittime_us);
PrrtTimer_submit(socket->retransmissionTimer, &deadline, &task);
}
void PrrtDataTransmitter_transmit(PrrtSocket *sock_ptr, PrrtPacket *packet) {
XlapTimeStampClock(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitStart);
XlapTimeStampCycle(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitStart);
if (sock_ptr->receiveBlock == NULL) {
sock_ptr->receiveBlock = PrrtBlock_create(PrrtCodingConfiguration_copy(sock_ptr->codingParameters), PrrtCoder_copy(sock_ptr->coder), packet->sequenceNumber);
sock_ptr->receiveBlock->senderBlock = true;
}
packet->index = (uint8_t) (packet->sequenceNumber - sock_ptr->receiveBlock->baseSequenceNumber);
......@@ -174,47 +225,48 @@ void PrrtDataTransmitter_transmit(PrrtSocket *sock_ptr, PrrtPacket *packet) {
PrrtPacket *packetToSend = PrrtPacket_copy(packet);
debug(DEBUG_DATATRANSMITTER, "Send: %i", packet->sequenceNumber);
send_packet(sock_ptr, packetToSend);
XlapTimeStampClock(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
XlapTimeStampCycle(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
PrrtBlock_insert_data_packet(sock_ptr->receiveBlock, packet);
// TODO: redundancy should only be sent when necessary
if (PrrtBlock_encode_ready(sock_ptr->receiveBlock)) {
uint32_t j = 0;
unsigned int redundancy_seqno = sock_ptr->sequenceNumberRedundancy;
XlapTimeStampCycle(sock_ptr, ts_redundancy_packet, redundancy_seqno, PrrtEncodeStart);
PrrtBlock_encode(sock_ptr->receiveBlock, &sock_ptr->sequenceNumberRedundancy);
XlapTimeStampCycle(sock_ptr, ts_redundancy_packet, redundancy_seqno, PrrtEncodeEnd);
uint32_t redundancyPackets = List_count(sock_ptr->receiveBlock->redundancyPackets);
for (j = 0; j < redundancyPackets; j++) {
PrrtPacket *red_pkt = PrrtBlock_get_first_red_data(sock_ptr->receiveBlock);
send_packet(sock_ptr, red_pkt);
int sendResult = send_packet(sock_ptr, packetToSend);
if (sendResult) {
XlapTimeStampClock(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
XlapTimeStampCycle(sock_ptr, ts_data_packet, packet->sequenceNumber, PrrtTransmitEnd);
if(PrrtBlock_insert_data_packet(sock_ptr->receiveBlock, packet) == false) {
PERROR("Failed to insert packet: %d", packet->sequenceNumber);
}
PrrtBlock_destroy(sock_ptr->receiveBlock);
sock_ptr->receiveBlock = NULL;
if (PrrtBlock_encode_ready(sock_ptr->receiveBlock)) {
unsigned int redundancy_seqno = sock_ptr->sequenceNumberRedundancy;
XlapTimeStampCycle(sock_ptr, ts_redundancy_packet, redundancy_seqno, PrrtEncodeStart);
PrrtBlock_encode(sock_ptr->receiveBlock, &sock_ptr->sequenceNumberRedundancy);
XlapTimeStampCycle(sock_ptr, ts_redundancy_packet, redundancy_seqno, PrrtEncodeEnd);
RetransmissionTimerArgs* args = (RetransmissionTimerArgs*) calloc(1, sizeof(RetransmissionTimerArgs));
args->block = sock_ptr->receiveBlock;
sock_ptr->receiveBlock = NULL;
args->socket = sock_ptr;
retransmission_round_handler(args);
}
} else {
PrrtPacket_destroy(packet);
}
}
void *PrrtDataTransmitter_send_data_loop(void *ptr) {
PrrtSocket *sock_ptr = ptr;
PrrtSocket *s = ptr;
while (1) {
ListNode *job;
do {
job = Pipe_pull(sock_ptr->sendDataQueue);
if (PrrtSocket_closing(sock_ptr)) {
if (sock_ptr->receiveBlock != NULL) {
PrrtBlock_destroy(sock_ptr->receiveBlock);
sock_ptr->receiveBlock = NULL;
job = Pipe_pull(s->sendDataQueue);
if (PrrtSocket_closing(s)) {
if (s->receiveBlock != NULL) {
PrrtBlock_destroy(s->receiveBlock);
s->receiveBlock = NULL;
}
return NULL;
}
} while (!job);
PrrtPacket *packet = PrrtPacket_byListNode(job);
PrrtDataTransmitter_transmit(sock_ptr, packet);
PrrtDataTransmitter_transmit(s, packet);
}
}
This diff is collapsed.
......@@ -8,6 +8,7 @@
#include <netdb.h>
#include "stores/inFlightPacketStore.h"
#include "bbr.h"
#include "types/applicationConstraints.h"
#include "types/channelStateInformation.h"
......@@ -18,6 +19,7 @@ typedef struct prrtReceiver {
PrrtChannelStateInformation *csi;
pthread_mutex_t lock;
pthread_cond_t wait_for_space;
atomic_bool closing;
BBR* bbr;
......@@ -32,17 +34,22 @@ PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port, prrtByteCount
void PrrtReceiver_add_outstanding_packet_state(PrrtReceiver *recv, PrrtPacket *packet, prrtTimestamp_t sentTime);
prrtByteCount_t PrrtReceiver_get_pipe(PrrtReceiver *recv);
void PrrtReceiver_check_rto(PrrtReceiver *recv, prrtSequenceNumber_t i, prrtPacketType_t param);
void PrrtReceiver_rto_check(PrrtReceiver *recv, PrrtApplicationConstraints *constraints);
void PrrtReceiver_on_application_write(PrrtReceiver *receiver, uint32_t i, prrtSequenceNumber_t i1);
void PrrtReceiver_on_ack(PrrtReceiver *receiver, PrrtPacketFeedbackPayload * feedbackPayload, prrtTimestamp_t receiveTime, prrtTimedelta_t rtt);
void PrrtReceiver_on_application_write(PrrtReceiver *receiver, uint32_t send_queue_length, prrtSequenceNumber_t sequenceNumber);
void PrrtReceiver_on_ack(PrrtReceiver *receiver, PrrtPacketFeedbackPayload *feedbackPayload, prrtTimestamp_t receiveTime,
prrtTimedelta_t rtt, PrrtApplicationConstraints *constraints);
void PrrtReceiver_wait_for_space(PrrtReceiver *receiver);
uint32_t PrrtReceiver_get_retransmission_delay(PrrtReceiver *socket, PrrtApplicationConstraints *applicationConstraints);
bool PrrtReceiver_wait_for_space(PrrtReceiver *receiver, prrtByteCount_t maximum_payload_size,
PrrtApplicationConstraints *pConstraints);
prrtByteCount_t PrrtReceiver_get_space(PrrtReceiver *receiver);
double PrrtReceiver_getBBRPacingRate(PrrtReceiver *receiver);
prrtDeliveryRate_t PrrtReceiver_get_BBR_btlDr(PrrtReceiver *receiver);
void PrrtReceiver_interrupt(PrrtReceiver *receiver);
bool PrrtReceiver_destroy(PrrtReceiver *receiver);
#endif //PRRT_RECEIVER_H
......@@ -18,6 +18,7 @@
#include "stores/deliveredPacketTable.h"
#include "types/packetTimeout.h"
#include "socket.h"
#include "timer.h"
static inline prrtPacketLength_t deliver_packet(const PrrtSocket *s, void *buffer, PrrtPacket *packet, struct sockaddr* addr) {
size_t timespec_size = sizeof(struct timespec);
......@@ -56,6 +57,8 @@ PrrtSocket *PrrtSocket_create(prrtByteCount_t maximum_payload_size, prrtTimedelt
s->isHardwareTimestamping = false;
s->interfaceName = NULL;
s->retransmissionTimer = PrrtTimer_create(3);
s->isThreadPinning = false;
PrrtClock_init(&s->clock);
......@@ -217,7 +220,7 @@ bool PrrtSocket_connect(PrrtSocket *s, const char *host, const uint16_t port) {
(void *) s) == EXIT_SUCCESS, "Cannot create send thread.");
return true;
error:
PERROR("PrrtSocket_connect failed.%s","");
PERROR("PrrtSocket_connect() failed.");
return false;
}
......@@ -270,23 +273,27 @@ bool PrrtSocket_closing(PrrtSocket *s) {
}
bool PrrtSocket_pace(PrrtSocket *s) {
bool result = true;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (s->pacingEnabled && s->nextSendTime != 0) {
debug(DEBUG_DATATRANSMITTER, "About to check for pacing.");
prrtTimeDifference_t diff = 0;
do {
if(PrrtSocket_closing(s)) {
result = false;
break;
}
prrtTimeDifference_t now = (prrtTimeDifference_t) PrrtClock_get_current_time_us();
diff = ((prrtTimeDifference_t) s->nextSendTime) - now;
if (diff > 0) {
usleep_nano((uint32_t) diff);
if(PrrtSocket_closing(s)) {
return false;
}
}
} while (diff > 0);
} else {
usleep_nano(1);
}
return true;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
return result;
}
int32_t PrrtSocket_receive_asap(PrrtSocket *s, void *buf_ptr, struct sockaddr* addr) {
......@@ -352,27 +359,38 @@ int32_t PrrtSocket_receive_ordered_timedwait(PrrtSocket *s, void *buf_ptr, struc
int PrrtSocket_interrupt(PrrtSocket *s) {
debug(DEBUG_SOCKET, "PrrtSocket_interrupt().");
atomic_store_explicit(&s->closing, true, memory_order_release);
if (s->packetDeliveryStore != NULL) {
PrrtPacketDeliveryStore_interrupt(s->packetDeliveryStore);
}
if(s->receiver != NULL) {
PrrtReceiver_interrupt(s->receiver);
}
if(s->sendDataQueue != NULL) {
Pipe_wake(s->sendDataQueue);
}
if (s->retransmissionTimer != NULL) {
PrrtTimer_end(s->retransmissionTimer);
s->retransmissionTimer = NULL;
}
void **res = NULL;
if (s->sendDataThread != 0) {
check(pthread_cancel(s->sendDataThread) == EXIT_SUCCESS, "Cancel failed.");
check(pthread_join(s->sendDataThread, res) == EXIT_SUCCESS, "Join failed.");
check(pthread_attr_destroy(s->sendDataThreadAttr) == EXIT_SUCCESS, "Destroy failed.");
s->sendDataThread = 0;
}
if (s->receiveDataThread != 0) {
check(pthread_cancel(s->receiveDataThread) == EXIT_SUCCESS, "Cancel failed.");
check(pthread_join(s->receiveDataThread, res) == EXIT_SUCCESS, "Join failed.");
int cancelResult = pthread_cancel(s->receiveDataThread);
check(cancelResult == EXIT_SUCCESS, "Cancel failed: %d.", cancelResult);
int joinResult = pthread_join(s->receiveDataThread, res);
check(joinResult == EXIT_SUCCESS, "Join failed: %d.", joinResult);
check(pthread_attr_destroy(s->receiveDataThreadAttr) == EXIT_SUCCESS, "Destroy failed.");
s->receiveDataThread = 0;
}
......@@ -380,11 +398,12 @@ int PrrtSocket_interrupt(PrrtSocket *s) {
return EXIT_SUCCESS;
error:
PERROR("PrrtSocket_interrupt() failed.\n");
return EXIT_FAILURE;
}
int PrrtSocket_close(PrrtSocket *s) {
debug(DEBUG_SOCKET, "Closing socket.");
debug(DEBUG_SOCKET, "PrrtSocket_close() start.");
if (!PrrtSocket_closing(s)) {
check(PrrtSocket_interrupt(s) == EXIT_SUCCESS, "Interrupt failed.");
}
......@@ -466,7 +485,7 @@ int PrrtSocket_close(PrrtSocket *s) {
}
close(s->socketFd);
debug(DEBUG_SOCKET, "Socket closed.");
debug(DEBUG_SOCKET, "PrrtSocket_close() end.");
return 0;
error:
......@@ -515,11 +534,9 @@ PrrtCodingConfiguration *PrrtSocket_get_coding_parameters(PrrtSocket *s) {
bool PrrtSocket_cleanup(PrrtSocket *s) {
debug(DEBUG_CLEANUP, "PrrtSocket_cleanup");
if (s->packetTimeoutTable != NULL) {
List *expired_packets = PrrtPacketTimeoutTable_expire_packets(s->packetTimeoutTable,
PrrtClock_get_prrt_time_us(
&s->clock));
List *expired_packets = PrrtPacketTimeoutTable_expire_packets(s->packetTimeoutTable, PrrtClock_get_current_time_us());
uint32_t expired_count = List_count(expired_packets);
debug(DEBUG_CLEANUP, "EXPIRED");
debug(DEBUG_CLEANUP, "EXPIRED: %d", expired_count);
if (expired_count > 0) {
PrrtPacketTimeout *first = List_first(expired_packets);
prrtSequenceNumber_t firstSequenceNumberBase = (prrtSequenceNumber_t) (first->sequenceNumber -
......
......@@ -17,6 +17,7 @@
#include "types/lossStatistics.h"
#include "types/packet.h"
#include "clock.h"
#include "timer.h"
#include "xlap.h"
#include "receiver.h"
......@@ -87,6 +88,8 @@ typedef struct prrtSocket {
atomic_bool isThreadPinning;
prrtByteCount_t maximum_payload_size;
PrrtTimer *retransmissionTimer;
} PrrtSocket;
......
......@@ -80,9 +80,11 @@ void PrrtDataPacketStore_remove_range(PrrtDataPacketStore *store, List *res, prr
bool PrrtDataStore_insert(PrrtDataPacketStore *store, PrrtPacket *packet)
{
check(pthread_mutex_lock(&store->lock) == EXIT_SUCCESS, "Lock failed.");
debug(DEBUG_BLOCK, "PrrtDataStore_insert: %d", packet->sequenceNumber);
if(BPTree_get(store->dataStore, packet->sequenceNumber) == NULL) {
store->dataStore = BPTree_insert(store->dataStore, packet->sequenceNumber, packet);
check(pthread_mutex_unlock(&store->lock) == EXIT_SUCCESS, "Unlock failed.");
debug(DEBUG_BLOCK, "PrrtDataStore_size: %d", PrrtDataPacketStore_size(store));
return true;
}
check(pthread_mutex_unlock(&store->lock) == EXIT_SUCCESS, "Unlock failed.");
......
#include <stdint.h>
#include "inFlightPacketStore.h"
#include "../clock.h"
#include "../../util/common.h"
#include "../../util/dbg.h"
#include "inFlightPacketStore.h"
PrrtInFlightPacketStore* PrrtInFlightPacketStore_create(void)
......@@ -9,7 +10,8 @@ PrrtInFlightPacketStore* PrrtInFlightPacketStore_create(void)
PrrtInFlightPacketStore* packetStore = calloc(1, sizeof(PrrtInFlightPacketStore));
check_mem(packetStore);
packetStore->outstandingPackets = NULL;
packetStore->outstandingPackets_by_seqno = NULL;
packetStore->outstandingPackets_by_senttime = NULL;
return packetStore;
......@@ -20,66 +22,63 @@ PrrtInFlightPacketStore* PrrtInFlightPacketStore_create(void)
void PrrtInFlightPacketStore_add_outstanding_packet(PrrtInFlightPacketStore *packetStore, PrrtPacket *packet)
{
packetStore->outstandingPackets = BPTree_insert(packetStore->outstandingPackets, packet->sequenceNumber,
packetStore->outstandingPackets_by_seqno = BPTree_insert(packetStore->outstandingPackets_by_seqno, packet->sequenceNumber,
packet);
packetStore->packetQueueSize++;
packetStore->outstandingPackets_by_senttime = BPTree_insert(packetStore->outstandingPackets_by_senttime, packet->sent_time,
packet);
}
void* PrrtInFlightPacketStore_get_packet(PrrtInFlightPacketStore *packetStore, BPTreeKey_t seqNum)
void* PrrtInFlightPacketStore_get_packet_by_seqno(PrrtInFlightPacketStore *packetStore, BPTreeKey_t seqNum)
{
return BPTree_get(packetStore->outstandingPackets, seqNum);
return BPTree_get(packetStore->outstandingPackets_by_seqno, seqNum);
}
PrrtPacket* PrrtInFlightPacketStore_get_first_packet_before(PrrtInFlightPacketStore *packetStore, prrtSequenceNumber_t seqNum) {
if (seqNum >= SEQNO_SPACE/2) {
return BPTree_get_first_in_range(packetStore->outstandingPackets, seqNum - (SEQNO_SPACE/2), seqNum-1);
} else {
PrrtPacket* first = BPTree_get_first_in_range(packetStore->outstandingPackets, seqNum + (SEQNO_SPACE/2), SEQNO_SPACE - 1);
if (first != NULL) {
return first;
} else {
return BPTree_get_first_in_range(packetStore->outstandingPackets, 0, seqNum - 1);
}
}
void* PrrtInFlightPacketStore_get_packet_by_senttime(PrrtInFlightPacketStore *packetStore, prrtTimestamp_t senttime)
{
return BPTree_get(packetStore->outstandingPackets_by_senttime, senttime);
}
prrtByteCount_t PrrtInFlightPacketStore_remove_outstanding_packet(PrrtInFlightPacketStore *packetStore, BPTreeKey_t seqNum)
void PrrtInFlightPacketStore_remove_outstanding_packet_by_seqno(PrrtInFlightPacketStore *packetStore,
BPTreeKey_t seqNum)
{
prrtByteCount_t lostBytes = 0;
PrrtPacket* outstanding_packet = (PrrtPacket*) BPTree_get(packetStore->outstandingPackets, seqNum);
PrrtPacket* outstanding_packet = (PrrtPacket*) BPTree_get(packetStore->outstandingPackets_by_seqno, seqNum);
if(outstanding_packet != NULL) {
packetStore->outstandingPackets = BPTree_delete(packetStore->outstandingPackets, seqNum);
packetStore->packetQueueSize--;
// TODO: Cleanup and loss marking. Make this more approriate with a "timeout".
List *packetStateList = List_create();
if(seqNum >= SEQNO_SPACE/2) {
BPTree_get_range(packetStore->outstandingPackets, packetStateList, seqNum - (SEQNO_SPACE / 2), seqNum - 1);
} else {
BPTree_get_range(packetStore->outstandingPackets, packetStateList, 0, seqNum - 1);
BPTree_get_range(packetStore->outstandingPackets, packetStateList, seqNum + (SEQNO_SPACE / 2), SEQNO_SPACE - 1);
}
while (List_count(packetStateList) > 0) {
PrrtPacket *packet = List_shift(packetStateList);
lostBytes += packet->payloadLength;
packetStore->outstandingPackets = BPTree_delete(packetStore->outstandingPackets, packet->sequenceNumber);
PrrtPacket_destroy(packet);
}
packetStore->outstandingPackets_by_seqno = BPTree_delete(packetStore->outstandingPackets_by_seqno, seqNum);
packetStore->outstandingPackets_by_senttime = BPTree_delete(packetStore->outstandingPackets_by_senttime, outstanding_packet->sent_time);
PrrtPacket_destroy(outstanding_packet);
List_destroy(packetStateList);
}
}
prrtByteCount_t PrrtInFlightPacketStore_clear_before(PrrtInFlightPacketStore *packetStore,
prrtTimestamp_t time) {
prrtByteCount_t lostBytes = 0;
List *packetStateList = List_create();
if(time >= HALF_TIMESTAMP) {
BPTree_get_range(packetStore->outstandingPackets_by_senttime, packetStateList, time - HALF_TIMESTAMP, time - 1);
} else {
BPTree_get_range(packetStore->outstandingPackets_by_senttime, packetStateList, 0, time - 1);
BPTree_get_range(packetStore->outstandingPackets_by_senttime, packetStateList, time + HALF_TIMESTAMP, MAX_TIMESTAMP);
}
while (List_count(packetStateList) > 0) {
PrrtPacket *packet = List_shift(packetStateList);
lostBytes += packet->payloadLength;
packetStore->outstandingPackets_by_seqno = BPTree_delete(packetStore->outstandingPackets_by_seqno, packet->sequenceNumber);
packetStore->outstandingPackets_by_senttime = BPTree_delete(packetStore->outstandingPackets_by_senttime, packet->sent_time);
PrrtPacket_destroy(packet);
}
List_destroy(packetStateList);
return lostBytes;
}
bool PrrtInFlightPacketStore_destroy(PrrtInFlightPacketStore *packetStore)
{
if (packetStore->outstandingPackets != NULL) {
if (packetStore->outstandingPackets_by_seqno != NULL) {
List *packetStateList = List_create();
BPTree_get_range(packetStore->outstandingPackets, packetStateList, 0, SEQNO_SPACE - 1);
BPTree_get_range(packetStore->outstandingPackets_by_seqno, packetStateList, 0, SEQNO_SPACE - 1);
while (List_count(packetStateList) > 0) {
PrrtPacket *packet = List_shift(packetStateList);
packetStore->outstandingPackets = BPTree_delete(packetStore->outstandingPackets, packet->sequenceNumber);
packetStore->outstandingPackets_by_seqno = BPTree_delete(packetStore->outstandingPackets_by_seqno, packet->sequenceNumber);
packetStore->outstandingPackets_by_senttime = BPTree_delete(packetStore->outstandingPackets_by_senttime, packet->sent_time);
PrrtPacket_destroy(packet);
}
......@@ -88,8 +87,3 @@ bool PrrtInFlightPacketStore_destroy(PrrtInFlightPacketStore *packetStore)
free(packetStore);
return true;
}
uint32_t PrrtInFlightPacketStore_get_queue_size(PrrtInFlightPacketStore *packetStore)
{
return packetStore->packetQueueSize;
}
\ No newline at end of file
......@@ -5,17 +5,19 @@
#include "../types/packet.h"
typedef struct inFlightPackets {
BPTreeNode* outstandingPackets;
uint32_t packetQueueSize;
BPTreeNode* outstandingPackets_by_seqno;
BPTreeNode* outstandingPackets_by_senttime;
} PrrtInFlightPacketStore;
PrrtInFlightPacketStore* PrrtInFlightPacketStore_create(void);
void PrrtIn