Skip to content

Commit

Permalink
fix alarm bug
Browse files Browse the repository at this point in the history
  • Loading branch information
SoonyangZhang committed May 8, 2022
1 parent 08caac8 commit 13085d5
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 11 deletions.
40 changes: 32 additions & 8 deletions quic/model/ns3-quic-alarm-engine.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <iostream>
#include <string>
#include <limits>
#include <vector>

Expand All @@ -12,6 +13,7 @@
#include "ns3-quic-alarm-engine.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("Ns3QuicAlarmEngine");
#define MOD_DEBUG 1
namespace quic{
Ns3QuicAlarmEngine::Ns3QuicAlarmEngine(Perspective role):
role_(role),
Expand All @@ -34,7 +36,10 @@ void Ns3QuicAlarmEngine::RegisterAlarm(int64_t timeout_us,AlarmCB* ac){
bool update=false;
ns3::Time now=ns3::Simulator::Now();
int64_t now_us=now.GetMicroSeconds();
if(timeout_us<=now_us){
if(timeout_us<now_us){
#if (MOD_DEBUG)
NS_LOG_FUNCTION(now_us<<timeout_us);
#endif
timeout_us=now_us;
}
if(alarm_map_.empty()){
Expand All @@ -51,7 +56,7 @@ void Ns3QuicAlarmEngine::RegisterAlarm(int64_t timeout_us,AlarmCB* ac){
all_alarms_.insert(ac);
ac->OnRegistration(alarm_iter,this);
}
if(update){
if((!timer_.IsRunning())||update){
UpdateTimer();
}

Expand All @@ -63,15 +68,24 @@ void Ns3QuicAlarmEngine::UnregisterAlarm(const AlarmRegToken & iterator_token){
cb->OnUnregistration();
}
Ns3QuicAlarmEngine::AlarmRegToken Ns3QuicAlarmEngine::ReregisterAlarm(AlarmRegToken &iterator_token, int64_t timeout_us){
int64_t now_us=ns3::Simulator::Now().GetMicroSeconds();
AlarmCB* cb = iterator_token->second;
int64_t last_us=iterator_token->first;
alarm_map_.erase(iterator_token);
NS_ASSERT(!alarm_map_.empty());
auto i=alarm_map_.begin();
int64_t next_timeout_us=i->first;
#if (MOD_DEBUG)
if(timeout_us<=now_us){
NS_LOG_FUNCTION(now_us<<timeout_us<<next_timeout_us<<last_us);
}
#endif
auto ret=alarm_map_.emplace(timeout_us, cb);
if(timeout_us<next_timeout_us){
if((!timer_.IsRunning())||(timeout_us<next_timeout_us)){
UpdateTimer();
}
NS_ASSERT_MSG(timer_.IsRunning(),now_us<<":"<<timeout_us
<<":"<<next_timeout_us<<":"<<alarm_map_.size());
return ret;
}
void Ns3QuicAlarmEngine::UpdateTimer(){
Expand All @@ -80,10 +94,10 @@ void Ns3QuicAlarmEngine::UpdateTimer(){
}
if(alarm_map_.empty()){ return ;}
auto i=alarm_map_.begin();
ns3::Time now=ns3::Simulator::Now();
ns3::Time future=ns3::MicroSeconds(i->first);
NS_ASSERT(future>=now);
ns3::Time next=future-now;
int64_t now_us=ns3::Simulator::Now().GetMicroSeconds();
int64_t future_us=i->first;
NS_ASSERT_MSG(future_us>=now_us,now_us<<":"<<future_us<<":"<<alarm_map_.size());
ns3::Time next=ns3::MicroSeconds(future_us-now_us);
timer_=ns3::Simulator::Schedule(next,&Ns3QuicAlarmEngine::OnTimeout,this);
}
void Ns3QuicAlarmEngine::OnTimeout(){
Expand All @@ -92,6 +106,7 @@ void Ns3QuicAlarmEngine::OnTimeout(){
TimeToAlarmCBMap::iterator erase_it;
std::vector<AlarmCB*> cbs;
bool has_event=false;
int64_t next_timeout_us=0;
for(auto i=alarm_map_.begin();i!=alarm_map_.end();){
if(i->first>now_us){
break;
Expand All @@ -106,7 +121,16 @@ void Ns3QuicAlarmEngine::OnTimeout(){
}
for(auto it=cbs.begin();it!=cbs.end();it++){
AlarmCB *cb=(*it);
int64_t next_timeout_us=cb->OnAlarm();
int c=0;
do{
next_timeout_us=cb->OnAlarm();
c++;
#if (MOD_DEBUG)
if((next_timeout_us>0)&&(next_timeout_us<=now_us)){
NS_LOG_FUNCTION(now_us<<next_timeout_us<<c);
}
#endif
}while((next_timeout_us>0)&&(next_timeout_us<=now_us));
if(next_timeout_us>0){
RegisterAlarm(next_timeout_us,cb);
}
Expand Down
62 changes: 62 additions & 0 deletions quic/model/ns3-quic-congestion-factory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "gquiche/quic/core/congestion_control/bbr2_sender.h"
#include "gquiche/quic/core/congestion_control/bbr_sender.h"
#include "gquiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"

#include "ns3-quic-congestion-factory.h"
#include "ns3-quic-no-destructor.h"
namespace quic{
class Ns3QuicCongestionFactory:public AbstractCongestionFactory{
public:
~Ns3QuicCongestionFactory() override{}
SendAlgorithmInterface* Create(
const QuicClock* clock,
const RttStats* rtt_stats,
const QuicUnackedPacketMap* unacked_packets,
CongestionControlType type,
QuicRandom* random,
QuicConnectionStats* stats,
QuicPacketCount initial_congestion_window,
QuicPacketCount max_congestion_window,
SendAlgorithmInterface* old_send_algorithm) override;
};
SendAlgorithmInterface* Ns3QuicCongestionFactory::Create(
const QuicClock* clock,
const RttStats* rtt_stats,
const QuicUnackedPacketMap* unacked_packets,
CongestionControlType type,
QuicRandom* random,
QuicConnectionStats* stats,
QuicPacketCount initial_congestion_window,
QuicPacketCount max_congestion_window,
SendAlgorithmInterface* old_send_algorithm){
int v=type;
SendAlgorithmInterface *algo=nullptr;
if(kBBR==v){
algo=new BbrSender(clock->ApproximateNow(), rtt_stats, unacked_packets,
initial_congestion_window, max_congestion_window,
random, stats);
}else if(kBBRv2==v){
algo=new Bbr2Sender(clock->ApproximateNow(), rtt_stats, unacked_packets,
initial_congestion_window, max_congestion_window, random, stats,
old_send_algorithm &&
old_send_algorithm->GetCongestionControlType() == kBBR
? static_cast<BbrSender*>(old_send_algorithm)
: nullptr);
}else if(kCubicBytes==v){
algo=new TcpCubicSenderBytes(clock, rtt_stats, false /* don't use Reno */,
initial_congestion_window, max_congestion_window, stats);
}else{
algo=new TcpCubicSenderBytes(clock, rtt_stats, true /* use Reno */,
initial_congestion_window,
max_congestion_window, stats);
}
return algo;
}
Ns3QuicCongestionFactory* CreateCongestionFactory() {
static NoDestructor<Ns3QuicCongestionFactory> singleton;
return singleton.get();
}
void RegisterExternalCongestionFactory(){
SetCongestionFactory(CreateCongestionFactory());
}
}
9 changes: 9 additions & 0 deletions quic/model/ns3-quic-congestion-factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once
#include "gquiche/quic/core/congestion_control/send_algorithm_interface.h"
namespace quic{
enum CongestionControlType2{
kCC0=CongestionControlType::kBBRv2,
kSelfDefineCC1,
};
void RegisterExternalCongestionFactory();
}
34 changes: 34 additions & 0 deletions quic/model/ns3-quic-no-destructor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once
namespace quic{
//copy from leveldb
// Wraps an instance whose destructor is never called.
//
// This is intended for use with function-level static variables.
template <typename InstanceType>
class NoDestructor {
public:
template <typename... ConstructorArgTypes>
explicit NoDestructor(ConstructorArgTypes&&... constructor_args) {
static_assert(sizeof(instance_storage_) >= sizeof(InstanceType),
"instance_storage_ is not large enough to hold the instance");
static_assert(
alignof(decltype(instance_storage_)) >= alignof(InstanceType),
"instance_storage_ does not meet the instance's alignment requirement");
new (&instance_storage_)
InstanceType(std::forward<ConstructorArgTypes>(constructor_args)...);
}

~NoDestructor() = default;

NoDestructor(const NoDestructor&) = delete;
NoDestructor& operator=(const NoDestructor&) = delete;

InstanceType* get() {
return reinterpret_cast<InstanceType*>(&instance_storage_);
}

private:
typename std::aligned_storage<sizeof(InstanceType),
alignof(InstanceType)>::type instance_storage_;
};
}
2 changes: 2 additions & 0 deletions quic/wscript
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def build(bld):
'model/ns3-quic-client-app.cc',
'model/ns3-quic-client-session.cc',
'model/ns3-quic-clock.cc',
'model/ns3-quic-congestion-factory.cc',
'model/ns3-quic-connection-helper.cc',
'model/ns3-quic-dispatcher.cc',
'model/ns3-quic-flags.cc',
Expand All @@ -58,6 +59,7 @@ def build(bld):
'model/ns3-quic-backend.h',
'model/ns3-quic-channel.h',
'model/ns3-quic-clock.h',
'model/ns3-quic-congestion-factory.h',
'model/ns3-quic-client.h',
'model/ns3-quic-client-app.h',
'model/ns3-quic-server.h',
Expand Down
8 changes: 5 additions & 3 deletions scratch/quic-main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void test_arg_config(int argc, char* argv[]){
}
void test_app(Time app_start,Time app_stop,uint8_t client_log_flag,
uint8_t server_log_flag,quic::BackendType type,const std::string &cc_name){
uint64_t bps=4000000;
uint64_t bps=5000000;
uint32_t link_delay=100;//milliseconds;
uint32_t buffer_delay=300;//ms
std::string topo_id("1");
Expand Down Expand Up @@ -194,10 +194,11 @@ void test_app(Time app_start,Time app_stop,uint8_t client_log_flag,
std::cout<<"run time ms: "<<delta<<std::endl;
}
int main(int argc, char* argv[]){
//LogComponentEnable("QuicClientApp",LOG_LEVEL_ALL);
//LogComponentEnable("QuicServerApp",LOG_LEVEL_ALL);
LogComponentEnable("Ns3QuicBackendBase",LOG_LEVEL_ALL);
LogComponentEnable("Ns3QuicAlarmEngine",LOG_LEVEL_ALL);
//LogComponentEnable("Ns3QuicChannelBase",LOG_LEVEL_ALL);
//LogComponentEnable("QuicClientApp",LOG_LEVEL_ALL);
//LogComponentEnable("QuicServerApp",LOG_LEVEL_ALL);
std::string cc_type("cubic");
CommandLine cmd;
cmd.AddValue ("cc", "cctype",cc_type);
Expand All @@ -213,6 +214,7 @@ int main(int argc, char* argv[]){
quic::BackendType type=quic::BackendType::BANDWIDTH;
uint8_t client_log_flag=E_QC_IN_FLIGHT|E_QC_SEND_RATE;
uint8_t server_log_flag=E_QS_OWD|E_QS_LOST|E_QS_GOODPUT;
//RegisterExternalCongestionFactory();
test_app(Seconds(0.001),Seconds(200),client_log_flag,server_log_flag,type,cc_type);
return 0;
}

0 comments on commit 13085d5

Please sign in to comment.