Merge branch 'USNavalResearchLaboratory:master' into master

pull/85/head
mullerj 2023-06-19 17:02:21 -04:00 committed by GitHub
commit 86d8fb13d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1559 additions and 97 deletions

View File

@ -212,6 +212,7 @@ if(NORM_BUILD_EXAMPLES)
normMsgr
normStreamer
normCast
chant
normClient
normServer
#wintest

1424
examples/chant.cpp Executable file

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
#include <sys/timerfd.h>
#endif // LINUX
const unsigned int LOOP_MAX = 100;
const unsigned int LOOP_MAX = 1;
// Setting SHOOT_FIRST to non-zero means that an ACK request
// will be used to advance the acking "watermark" point
@ -577,7 +577,7 @@ bool NormStreamer::OpenNormSession(NormInstanceHandle instance, const char* addr
NormSetLoopback(norm_session, loopback);
// Set some default parameters (maybe we should put parameter setting in Start())
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_STREAM);
NormSetDefaultSyncPolicy(norm_session, NORM_SYNC_CURRENT);
if (!is_multicast)
NormSetDefaultUnicastNack(norm_session, true);
@ -711,7 +711,7 @@ bool NormStreamer::Start(bool sender, bool receiver)
void NormStreamer::ReadInputSocket()
{
unsigned int loopCount = 0;
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (input_needed && input_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -739,7 +739,7 @@ void NormStreamer::ReadInputSocket()
input_ready = false;
}
}
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::ReadInputSocket()
void NormStreamer::ReadInput()
@ -748,7 +748,7 @@ void NormStreamer::ReadInput()
// The loop count makes sure we don't spend too much time here
// before going back to the main loop to handle NORM events, etc
unsigned int loopCount = 0;
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (input_needed && input_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -766,7 +766,9 @@ void NormStreamer::ReadInput()
assert(input_index < input_msg_length);
numBytes = input_msg_length - input_index;
}
TRACE("reading STDIN ...\n");
ssize_t result = read(input_fd, input_buffer + input_index, numBytes);
TRACE(" result: %d\n", (int)result);
if (result > 0)
{
input_index += result;
@ -833,7 +835,7 @@ void NormStreamer::ReadInput()
break;
}
} // end while (input_needed && input_ready)
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::ReadInput()
void NormStreamer::SendData()
@ -1000,7 +1002,7 @@ void NormStreamer::RecvData()
// before going back to the main loop to handle NORM events, etc
unsigned int loopCount = 0;
// Reads data from rx_stream to available output_buffer
NormSuspendInstance(NormGetInstance(norm_session));
//NormSuspendInstance(NormGetInstance(norm_session));
while (rx_needed && rx_ready && (loopCount < LOOP_MAX))
{
loopCount++;
@ -1065,7 +1067,7 @@ void NormStreamer::RecvData()
WriteOutput();
}
}
NormResumeInstance(NormGetInstance(norm_session));
//NormResumeInstance(NormGetInstance(norm_session));
} // end NormStreamer::RecvData()
@ -1120,8 +1122,8 @@ void NormStreamer::WriteOutput()
if (0 != output_bucket_depth)
{
// Debit output token bucket since it's active
if (result > output_bucket_count)
TRACE("result:%d output_bucket_count:%u\n", (int)result, output_bucket_count);
//if (result > output_bucket_count)
// TRACE("result:%d output_bucket_count:%u\n", (int)result, output_bucket_count);
ASSERT(output_bucket_count >= result);
output_bucket_count -= result;
}
@ -1174,7 +1176,7 @@ void NormStreamer::HandleNormEvent(const NormEvent& event)
break;
case NORM_GRTT_UPDATED:
//fprintf(stderr, "new GRTT = %lf\n", NormGetGrttEstimate(norm_session));
fprintf(stderr, "new GRTT = %lf\n", NormGetGrttEstimate(norm_session));
break;
case NORM_ACKING_NODE_NEW:
@ -1453,7 +1455,7 @@ int main(int argc, char* argv[])
unsigned long outputSocketBufferSize = 0; // 6*1024*1024;
unsigned long txSocketBufferSize = 0; // 6*1024*1024;
unsigned long rxSocketBufferSize = 0; // 6*1024*1024;
unsigned long streamBufferSize = 1*1024*1024;
unsigned long streamBufferSize = 10*1024*1024;
// Instantiate a NormStreamer and set default params
NormStreamer normStreamer;
@ -2136,6 +2138,7 @@ int main(int argc, char* argv[])
int maxfd = -1;
int fdMask = 0;
bool waitOnNorm = false;
bool waitOnInput = false;
double timeoutInterval = -1.0;
if (send)
{
@ -2151,6 +2154,7 @@ int main(int argc, char* argv[])
FD_SET(inputfd, &fdsetInput);
if (inputfd > maxfd) maxfd = inputfd;
fdMask |= 0x01;
waitOnInput = true;
}
}
else
@ -2268,6 +2272,7 @@ int main(int argc, char* argv[])
timeout.tv_sec = timeout.tv_usec = 0;
}
#endif // if/else LINUX
//ßTRACE("waitOnNorm:%d waitOnInput:%d\n", waitOnNorm, waitOnInput);
int result = select(maxfd+1, &fdsetInput, &fdsetOutput, NULL, timeoutPtr);
switch (result)
{
@ -2304,9 +2309,14 @@ int main(int argc, char* argv[])
}
// We always clear out/handle pending NORM API events
// (to keep event queue from building up)
unsigned int eventCount = 0;
const unsigned int maxBurstCount = 50;
NormEvent event;
while (NormGetNextEvent(normInstance, &event, false))
while ((eventCount < maxBurstCount) && (NormGetNextEvent(normInstance, &event, false)))
{
normStreamer.HandleNormEvent(event);
eventCount += 1;
}
struct timeval thisTime;
gettimeofday(&thisTime, NULL);

View File

@ -207,6 +207,16 @@ normCastApp: $(CASTAPP_OBJ) libnorm.a $(LIBPROTO)
mkdir -p ../bin
cp $@ ../bin/$@
# (chant) NORM command-line chat sender/receiver
CHANT_SRC = $(EXAMPLE)/chant.cpp
CHANT_OBJ = $(CHANT_SRC:.cpp=.o)
chant: $(CHANT_OBJ) libnorm.a $(LIBPROTO)
$(CC) $(CFLAGS) -o $@ $(CHANT_OBJ) $(LDFLAGS) libnorm.a $(LIBPROTO) $(LIBS)
mkdir -p ../bin
cp $@ ../bin/$@
# These are the new "NormSocket" API extension examples
SERVER_SRC = $(EXAMPLE)/normServer.cpp $(EXAMPLE)/normSocket.cpp
SERVER_OBJ = $(SERVER_SRC:.cpp=.o)

@ -1 +1 @@
Subproject commit c1907cee5e36536be2dbdd7fabcb1a7ec8472288
Subproject commit 7323fd3455ea6c16137ad3b84c950d74cc21055b

View File

@ -1637,12 +1637,15 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
bool presetStream = false;
NormObject* obj = NULL;
bool doInsert = true;
bool seen = false;
switch (status)
{
case OBJ_PENDING:
{
if (NULL != (obj = rx_table.Find(objectId)))
{
// This checks for an object that's been "seen" but did not
// include Object FTI information previously.
if (0 == obj->GetSize().GetOffset())
{
// It's a seen object for which are awaiting FTI
@ -1651,6 +1654,7 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
gotFTI = true;
obj->SetNackingMode(default_nacking_mode);
doInsert = false;
seen = true;
// Intentionally pass through to case OBJ_NEW
}
else
@ -1759,7 +1763,7 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
if (GetFtiData(msg, ftiData) || session.GetPresetFtiData(ftiData))
gotFTI = true;
}
if (gotFTI)
if (gotFTI || presetStream) // this assumes presetStream matches if !gotFTI (if we get conflicting info, an abort/resync will be forced)
{
if (presetStream ||
obj->RxOpen(ftiData.GetObjectSize(),
@ -1791,7 +1795,7 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
NormBlockId syncId = blockId;
stream->Decrement(syncId, stream->GetPendingMaskSize() - 1);
if ((stream->Compare(blockId, NormBlockId(0)) >= 0) &&
(stream->Compare(syncId, NormBlockId(0)) <= 0))
(stream->Compare(syncId, NormBlockId(0)) <= 0) && !seen)
{
// Assume we are "in-range" of sender initial stream startup
syncId = NormBlockId(0);
@ -1835,8 +1839,8 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
(unsigned long)GetId(), (UINT16)objectId);
if (!presetStream) DeleteObject(obj);
obj = NULL;
}
}
} // end if/else (gotFTI : ((NormMsg::INFO != msgType) && msg.FlagIsSet(NormObjectMsg::FLAG_INFO)))
} // end if (NULL != obj)
break;
}
case OBJ_COMPLETE:
@ -1875,7 +1879,7 @@ void NormSenderNode::HandleObjectMessage(const NormObjectMsg& msg)
completion_count++;
}
}
}
} // end (if (NULL != obj)
switch (repair_boundary)
{
case BLOCK_BOUNDARY:

View File

@ -3073,22 +3073,23 @@ bool NormStreamObject::StreamUpdateStatus(NormBlockId blockId)
//stream_next_id = blockId + pending_mask.GetSize();
stream_next_id = blockId;
Increment(stream_next_id, pending_mask.GetSize());
if (NULL != sender)
{
if (read_init && (NormSenderNode::SYNC_CURRENT != sender->GetSyncPolicy()))
if ((NULL != sender) && read_init)
{
// This is a fresh rx stream, so init the read indices
read_init = false;
PLOG(PL_DEBUG, "NormStreamObject::StreamUpdateStatus() syncing stream to blockId: %lu\n",
(unsigned long)blockId.GetValue());
read_init = false;
read_index.block = blockId;
if (0 != blockId.GetValue()) stream_broken = true;
read_index.segment = 0;
read_index.offset = 0;
read_offset = 0;
sender->DecrementResyncCount(); // correction since stream sync here will falsely increment
if ((NormSenderNode::SYNC_CURRENT != sender->GetSyncPolicy()) &&
(0 != blockId.GetValue()))
{
stream_broken = true;
}
}
} // end if ((NULL != sender) && read_init)
// Since we're doing a resync including "read_init", dump any buffered data
// (TBD) this may not be necessary??? and is thus currently commented-out code
@ -3230,16 +3231,8 @@ bool NormStreamObject::WriteSegment(NormBlockId blockId,
NormSegmentId segmentId,
const char* segment)
{
UINT32 segmentOffset = NormDataMsg::ReadStreamPayloadOffset(segment);
if (read_init)
{
read_init = false;
read_index.block = blockId;
read_index.segment = segmentId;
read_index.offset = 0;
read_offset = segmentOffset;
read_ready = true;
}
//UINT32 segmentOffset = NormDataMsg::ReadStreamPayloadOffset(segment);
ASSERT(!read_init);
//if ((blockId < read_index.block) ||
if ((Compare(blockId, read_index.block) < 0) ||

View File

@ -2275,7 +2275,6 @@ void NormSession::TxSocketRecvHandler(ProtoSocket &theSocket,
unsigned int msgLength = NormMsg::MAX_SIZE;
while (true)
{
if (theSocket.RecvFrom(msg.AccessBuffer(),
msgLength,
msg.AccessAddress()))
@ -2631,6 +2630,7 @@ void NormTrace(const struct timeval &currentTime,
time_t secs = (time_t)currentTime.tv_sec;
struct tm *ct = gmtime(&secs);
#endif // if/else _WIN32_WCE
PLOG(PL_ALWAYS, "trace>%02d:%02d:%02d.%06lu ",
(int)ct->tm_hour, (int)ct->tm_min, (int)ct->tm_sec, (unsigned int)currentTime.tv_usec);
PLOG(PL_ALWAYS, "node>%lu %s>%s/%hu ", (unsigned long)localId, status, addr.GetHostString(), addr.GetPort());
@ -2741,12 +2741,13 @@ void NormTrace(const struct timeval &currentTime,
{
PLOG(PL_ALWAYS, "inst>%hu ", instId);
// look for NormCCFeedback extension
bool ccExt = false;
NormHeaderExtension ext;
while (msg.GetNextExtension(ext))
{
if (NormHeaderExtension::CC_FEEDBACK == ext.GetType())
{
clrFlag = ((NormCCFeedbackExtension &)ext).CCFlagIsSet(NormCC::CLR);
ccExt = true;
break;
}
}
@ -2775,6 +2776,23 @@ void NormTrace(const struct timeval &currentTime,
PLOG(PL_ALWAYS, "NACK ");
// TBD - provide deeper NACK inspection?
}
if (ccExt)
{
clrFlag = ((NormCCFeedbackExtension &)ext).CCFlagIsSet(NormCC::CLR);
// Print ccRtt (only valid if pcap file is from sender node)
double ccRtt = NormUnquantizeRtt(((NormCCFeedbackExtension &)ext).GetCCRtt());
double ccLoss = NormUnquantizeLoss32(((NormCCFeedbackExtension &)ext).GetCCLoss32());
PLOG(PL_ALWAYS, "ccRtt:%lf ccLoss:%lf ", ccRtt, ccLoss);
// Print locally measured rtt (only valid if pcap file is from sender node)
struct timeval grttResponse;
if (NormMsg::NACK == msgType)
static_cast<const NormNackMsg &>(msg).GetGrttResponse(grttResponse);
else
static_cast<const NormAckMsg &>(msg).GetGrttResponse(grttResponse);
double rtt = ProtoTime::Delta(ProtoTime(currentTime), ProtoTime(grttResponse));
PLOG(PL_ALWAYS, "rtt:%lf ", rtt);
}
break;
}

16
waf vendored

File diff suppressed because one or more lines are too long

View File

@ -231,6 +231,8 @@ def build(ctx):
'normStreamSend',
'normMsgr',
'normStreamer',
'normCast',
'chant',
'normClient',
'normServer',
#'wintest' # Windows only (can uncomment on Windows)