From 89309695626ba47a7e9f4c908a4d46c8b059df0f Mon Sep 17 00:00:00 2001 From: Hanoh Haim Date: Thu, 22 Dec 2016 11:35:11 +0200 Subject: [PATCH] stateful scheduler cleanup Signed-off-by: Hanoh Haim --- .gitignore | 10 + scripts/cap2/imix_64_fast.yaml | 28 ++ scripts/exp/imix-0-ex.erf | Bin 68104 -> 67928 bytes scripts/exp/imix-0.erf | Bin 68104 -> 67928 bytes scripts/exp/imix_64_fast-0-ex.erf | Bin 0 -> 13288 bytes scripts/exp/imix_v6-0-ex.erf | Bin 70928 -> 70720 bytes scripts/exp/imix_v6-0.erf | Bin 70928 -> 70720 bytes scripts/exp/ipv4_vlan-0-ex.erf | Bin 10648 -> 10560 bytes scripts/exp/ipv4_vlan-0.erf | Bin 10648 -> 10560 bytes scripts/exp/ipv6-0-ex.erf | Bin 13552 -> 13440 bytes scripts/exp/ipv6-0.erf | Bin 13552 -> 13440 bytes scripts/exp/ipv6_vlan-0-ex.erf | Bin 13552 -> 13440 bytes scripts/exp/ipv6_vlan-0.erf | Bin 13552 -> 13440 bytes scripts/exp/limit_multi_pkt-0.erf | Bin 30944 -> 30944 bytes scripts/exp/limit_single_pkt-0-ex.erf | Bin 6688 -> 6512 bytes scripts/exp/limit_single_pkt-0.erf | Bin 6688 -> 6512 bytes src/bp_gtest.cpp | 16 +- src/bp_sim.cpp | 77 +++-- src/bp_sim.h | 22 ++ src/gtest/bp_timer_gtest.cpp | 61 ++++ src/h_timer.cpp | 44 ++- src/h_timer.h | 68 ++++- src/h_timer_w.h | 533 ---------------------------------- 23 files changed, 293 insertions(+), 566 deletions(-) create mode 100644 scripts/cap2/imix_64_fast.yaml create mode 100644 scripts/exp/imix_64_fast-0-ex.erf delete mode 100644 src/h_timer_w.h diff --git a/.gitignore b/.gitignore index 0b6832f1..cf416ab6 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,16 @@ scripts/exp/udp_64B_vm_mask5.pcap scripts/exp/udp_64B_vm_mask6.pcap scripts/exp/stl_vm_enable0_cache_10-0.erf scripts/exp/stl_vm_enable1_cache_500-0.erf +scripts/exp/imix-0.erf +scripts/exp/imix_v6-0.erf +scripts/exp/ipv4_vlan-0.erf +scripts/exp/ipv6-0.erf +scripts/exp/ipv6_vlan-0.erf +scripts/exp/limit_multi_pkt-0.erf +scripts/exp/limit_single_pkt-0.erf +scripts/exp/imix_64_fast-0.erf +scripts/exp/pcap_mode2-0.erf + diff --git a/scripts/cap2/imix_64_fast.yaml b/scripts/cap2/imix_64_fast.yaml new file mode 100644 index 00000000..f259381c --- /dev/null +++ b/scripts/cap2/imix_64_fast.yaml @@ -0,0 +1,28 @@ +# +# Simple IMIX test 64B +# +- duration : 0.0001 + generator : + distribution : "seq" + clients_start : "16.0.0.1" + clients_end : "16.0.0.255" + servers_start : "48.0.0.1" + servers_end : "48.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + mac : [0x0,0x0,0x0,0x1,0x0,0x00] +# +# the templates are duplicated in purpose , to utilized all DRAM BW and get better performance, we should do it automaticly +# but for now it like this , you should have at least 8 +# + cap_info : + - name: cap2/udp_64B.pcap + cps : 1000000.0 + ipg : 10000 + rtt : 10000 + w : 1 + limit : 50 + diff --git a/scripts/exp/imix-0-ex.erf b/scripts/exp/imix-0-ex.erf index 4f6d3d9446e3387ae3411259e53c51cedd06799c..6f5f4f07a8ab6cd730e6d86f896f68810f316613 100755 GIT binary patch delta 1364 zcmYMzF=$#*6b9hj^WGyZmIlEw*&35ES<adDA?Ex0%c#YGA!ROmVP+;{HeJ?9P|_y3^=PRoWp!B`kC5|{yfSmKVE-a0(GJncd4v8#Z#b)^>8;XKG_3x7F|CL z)H%(YYdBv-VLDKk^>8a5r}sgXqxDSQ+YYbFD^ag@?Ee1pzH%Fu0IH(ZMQgCu6s@JT zwrCx#bw!J{))TFtXnoP{wKfoKDB6g%v1k*mO+}k&Z7$kEYs*9fP|-%_*u}>|^sScn z@NKK=wt#slouqr1PpjxxY6qj-!rcZ%$&0%bF7PT)s$ST^D4)~KXN*$Mn`?S5V3as# zG0K;8Z?sp5c7WO&fFt2@36}+*JiI(fz$~27(TAcT_W;hw^x@o~xVcbKA??GZVfO*b z;+7M)!fsXEx^)}IZCba*Zri#YcDvS%+3i`kuU!YzjlR}iQ@Hoc4ulrM#d@=@clCN4<$AkNPAK`!pi;NhJ1(8#1X+LVfx%53I0S6}4{FhEbbV zZL!+6YKPUXRby6rR_!zQEWE-Ke#g2`h6e%Am>`j;#g#1z!~L;HV`W)%2@~Nuknj>5mW-f4hKst1 zi8X1>U@!G1Mrr{!UBW*Ea^e;fvV@V9g}MyQ$VMep!7N?0(U9qaRQ9~wo+tO;_xar= z_sRXfcYj=f=f8#{9X9RB_fXqp+pdRf7XesY(BH^@iQvj9wL-g>QKbFz%2pU|a#!h_ z)*S)xM(VX%Iv&f|3akIx*oY4v*mf3rgLOr^*HR3i()zSTyJGb~Cz@{~Q^y88olgGJ zsnsbS=>O=Ou3+7EJ*Kz-3|qeN;b(gg329naT!rpup9Dth@T01~YVOf@Wv?RGUQik2 z7R9!wmsy;{1tD&UUdkS%mc=6ZI=A?9o(xe-cq}%|E$)FSomy75Tpj0@%<-NHY9WDH zZhUttLM>6ZH_9xFa|dU*#XsqqWtRR1XN+6i`|WXRIrKn!$So_=$pp1zHqRxwWvo21 zOfBtq2U7oAkpEaWkhENzY9#z(khA(^x-?qf1Q6C(B>m0o7YJdFB5Cs(g=9|%d+d^) zyAI!jK{@OK-W0;3JaSSICOM>FeIeZydN!SON?O>eB5U*94mu~>LL=poVo9r4RMdKR zz=h}ebYIAKthJ_e#$u-Db*G;Y=?ix0^bnY5Axh9wfzb~A~ zM)CWKa932gW=yVG;fk4DaqfC(awWJcX>u)dSIXo9fM_6g0qu0$Ls;p6)(fxE0$9E9 z8Wq6nh1X~YtX|d)uja4|q+X-{+VaRrMN=2j9DvuW_4H#Wp!M?E|J*_6v|f(1pNj#l z*TT7e7oHpSdY=1PDPxgDS$*jz_Ayq;)21?m<>@Z35Ul6NOR5akxgYau1wzJi=53m4~B-YVV`68KGMG{jFI;)seR?CRADLl{ixsTw7fds@tC@5?qxOs(>=F z%v7Zp`%*$xv(pb``T?>;D!-@uXu3?hRdefIi;TO4|LTc+MdsD|awD|MtXlVf+mgdB zkZQeHTiZ-dDzfjK-zM{F6*k;*%Dh^1POBAu=Vq}?t99qw4i}yq)p~sAy;7Nee=OlY F#D8qJep3Jd diff --git a/scripts/exp/imix-0.erf b/scripts/exp/imix-0.erf index 4f6d3d9446e3387ae3411259e53c51cedd06799c..6f5f4f07a8ab6cd730e6d86f896f68810f316613 100644 GIT binary patch delta 1364 zcmYMzF=$#*6b9hj^WGyZmIlEw*&35ES<adDA?Ex0%c#YGA!ROmVP+;{HeJ?9P|_y3^=PRoWp!B`kC5|{yfSmKVE-a0(GJncd4v8#Z#b)^>8;XKG_3x7F|CL z)H%(YYdBv-VLDKk^>8a5r}sgXqxDSQ+YYbFD^ag@?Ee1pzH%Fu0IH(ZMQgCu6s@JT zwrCx#bw!J{))TFtXnoP{wKfoKDB6g%v1k*mO+}k&Z7$kEYs*9fP|-%_*u}>|^sScn z@NKK=wt#slouqr1PpjxxY6qj-!rcZ%$&0%bF7PT)s$ST^D4)~KXN*$Mn`?S5V3as# zG0K;8Z?sp5c7WO&fFt2@36}+*JiI(fz$~27(TAcT_W;hw^x@o~xVcbKA??GZVfO*b z;+7M)!fsXEx^)}IZCba*Zri#YcDvS%+3i`kuU!YzjlR}iQ@Hoc4ulrM#d@=@clCN4<$AkNPAK`!pi;NhJ1(8#1X+LVfx%53I0S6}4{FhEbbV zZL!+6YKPUXRby6rR_!zQEWE-Ke#g2`h6e%Am>`j;#g#1z!~L;HV`W)%2@~Nuknj>5mW-f4hKst1 zi8X1>U@!G1Mrr{!UBW*Ea^e;fvV@V9g}MyQ$VMep!7N?0(U9qaRQ9~wo+tO;_xar= z_sRXfcYj=f=f8#{9X9RB_fXqp+pdRf7XesY(BH^@iQvj9wL-g>QKbFz%2pU|a#!h_ z)*S)xM(VX%Iv&f|3akIx*oY4v*mf3rgLOr^*HR3i()zSTyJGb~Cz@{~Q^y88olgGJ zsnsbS=>O=Ou3+7EJ*Kz-3|qeN;b(gg329naT!rpup9Dth@T01~YVOf@Wv?RGUQik2 z7R9!wmsy;{1tD&UUdkS%mc=6ZI=A?9o(xe-cq}%|E$)FSomy75Tpj0@%<-NHY9WDH zZhUttLM>6ZH_9xFa|dU*#XsqqWtRR1XN+6i`|WXRIrKn!$So_=$pp1zHqRxwWvo21 zOfBtq2U7oAkpEaWkhENzY9#z(khA(^x-?qf1Q6C(B>m0o7YJdFB5Cs(g=9|%d+d^) zyAI!jK{@OK-W0;3JaSSICOM>FeIeZydN!SON?O>eB5U*94mu~>LL=poVo9r4RMdKR zz=h}ebYIAKthJ_e#$u-Db*G;Y=?ix0^bnY5Axh9wfzb~A~ zM)CWKa932gW=yVG;fk4DaqfC(awWJcX>u)dSIXo9fM_6g0qu0$Ls;p6)(fxE0$9E9 z8Wq6nh1X~YtX|d)uja4|q+X-{+VaRrMN=2j9DvuW_4H#Wp!M?E|J*_6v|f(1pNj#l z*TT7e7oHpSdY=1PDPxgDS$*jz_Ayq;)21?m<>@Z35Ul6NOR5akxgYau1wzJi=53m4~B-YVV`68KGMG{jFI;)seR?CRADLl{ixsTw7fds@tC@5?qxOs(>=F z%v7Zp`%*$xv(pb``T?>;D!-@uXu3?hRdefIi;TO4|LTc+MdsD|awD|MtXlVf+mgdB zkZQeHTiZ-dDzfjK-zM{F6*k;*%Dh^1POBAu=Vq}?t99qw4i}yq)p~sAy;7Nee=OlY F#D8qJep3Jd diff --git a/scripts/exp/imix_64_fast-0-ex.erf b/scripts/exp/imix_64_fast-0-ex.erf new file mode 100644 index 0000000000000000000000000000000000000000..bc8bc1cc213fbdf4c16ea3095ce1d2c56012dd55 GIT binary patch literal 13288 zcmb8z`%l$%9LMo5hs)t6cL5JaKm4 z5e*rdF(o8KW6j(VqOxYCO}A=MO2ej3w`^J2(xtt$KcMI5Y>bT`9((P*!{>*mYiX;^ z(#IBHEzz$+%Zj@5Nxbt3w&q)w`}Us;qpuG~S(cwiKLM8gwB@j@@qv+FEx#apa7bvF z)pha54Nu&b{`>>iQpFV~;Ag}bqPSZ;va0OHyYV)p~NfpP$Zlv5u z;%-}k-Q9AdSmGY+$LI!ySS6KS#FZtB;sDo$8M8cr(7p-56r`Equi--rxJI~V(d1^O_rNX z+y|CpcfH&cxhcf;UxVG(;W&2J$jy+OLEM2c?AFT7l$%N1)t9lmO70A~Gl+Zt4eVCSb;)%R z*A~8&zLQmQv*czG_X{U>E9GX(%_i=aJnUA;&5@f!+~NnZTP`-yq!=^^#SI z*gYf{_mX?FusbL>SbI?~xits719EXM`Me0b{c=OK7xfZv33mJB;$HI9O6>N^4cA`O zOOoobYt&25d9mB0y%E}rdP(0d>>BlwnnCOu^^$u=vD>XX;9hd`6n4Ah#^}DNmwYyX zU87#I=_+=OddXt{ZSLrdi?6&K^xR*?%W7nvcygLiKt=fxwN%h0n^~%M)WOgxj zTjV-Cu$TN(j@@RtxR)HO!)}vYr}m;=($b7wqh7LTCw3dO7x$7W{n$0?B|rJFYt&2j zoxpCr?tptq)miMWlbfdR1L`GrU%{?XFS&6OyGFg_lgJMG{u=d?=2Yy~>b{w}FX|;v z=402Wmn6)?ZngHhv={Y~@kQ9Jl8bxE-ZJb~%FWhZ)Js;b#%_gN+)M6i#BRCVT9JAy=3EI>>Blwg~zdL)Jx*Wu)9omz`f+`CG3{SEzo^YFPY%( zuw2|rD#NzZchV=>Blw z$u-y=)ZSq2MZM(A>)0KTi+f2=8+QBUhH5YBB`>{$-9EXvm*fv&w^wes_M%?$*QeMu z>LnxJV7EtmBeWOwlE(AcHR>ggU&F3ZFNwA9pzmb2?tpvA4++@qk{hG@qF%Dcgd}sF%1Wu-l-$xR?C-8+MI)$x+)|^qn;7B@MCI zt=AoJFDXjL?mD??`aYmu5{iIdy(IDkcFX1FYA@;~-<`p( zQ7`HK1-oV1>(*Y>OP1fnu2C<^iR`5BuTd|#nu6VBx&!VdM?Baqkz1hqqFyq>-C?=7 Gm;4JnSr^j) literal 0 HcmV?d00001 diff --git a/scripts/exp/imix_v6-0-ex.erf b/scripts/exp/imix_v6-0-ex.erf index 2dd16e111f11d7973d5cdbfdb43b6cd80509835c..d52d8541d992f0e1e7a32208a7614ff094241d06 100755 GIT binary patch delta 1303 zcmYMyF=&%P6u@!secx9F6;Trj2!TK(CAN-kE}aUdLqJ^OP)NQ8G0Bo@2MIzQDwv|- zAWN2j1Wc`=;pTv3$&w{YmZ;RBLP4@*5)Am>-SypexsSdd_x}BOdh zZCOtgXnaSH7hPFO76|BRKq#3>6^IyULJZ|vx*> zHjLPGV#|na7CTn#ve>htVsT)_AvyT~*NG?kZ~b%hdSuYCLnj8EI&@~xQ%27$dd}$F uq6xeLysGJrXdcr4L#gx75)PxRhJzA delta 1582 zcmYM!aY&SB90%~;=Y3v{btrf0?Lab(yWCw?3kPH5(ajM#cFwHGM3CCuNli~<-nNP? zcEMfj&X#+aW6G&*HFnWNc`HUB8%}l(uaU)sY2uYe+^AzisNp>9d7t0I^Zs=|p6B5E z;rD!bfB6Alx`sz;ib$&PP4!$+9HGSp)nPH`;FVJc>dESQFN%58YbBo`d?UNHi9Fcg zl^dQ|NTke%+dsoT^|~Q|kg=6~Xl=oEWxidF<_C~GmHC~#SMI~1kG}0v+f4K%X1GYU zI((S^28p}Ki(Su8hez822sd16iK-Qr!W`V;*x#c?Vq@X%UiEqjy|fQI`n6D;{QA`) z5-s!M#hvn1mWo5g|HMg~)r(^{=Z0A>b`4Id#9i*iE1NHmv0!W(i;j~DhZhDd`NsFB z5-d6C@+Bd8adzJ{OAbvqXCQf?**?dTT{Y$uOFsNadJM@cQ<*eNHnq%VAo*rpVwoj( z+#k%cWF_Q}Ac<^qc=%LXDPd_X18M=>Di27MGGV%?yR zVn)!7y!_XS5$ne2e}$!pbz}0&bvAmfb))snGdp742%7)ej-VU1b-z{89NLYA^8-!< z-FUI_^J-wgq%rz(KivzAs((Fh&NvvUs|Uu5K-D46IREpOCScg&1xJA4d}qze8L5h= z#|5LEGx|m*I)QQUjaV0FwEl4+2s?mDdz8GNJ`Mw8^zsK$&Y0Zweh)A@Y`c0nW3|K9 z4~&6E(-1IjEoZNA#^L$DEB!J=Ae>BM% zZ$EWU17qpWw`MrwM5%QS7zM8wQ^0UsSzY3cJKgEDU}QKWY#d((M)g;HSOm8vDtQucfuvvy`JiNQPSZ3Aue{F4(%&KADF>j^U pS~Xs8zHOI9HDstpY|pJq8c3^g@4FLD8LIK@UTw9^8VVC##!G8`GfV&g diff --git a/scripts/exp/imix_v6-0.erf b/scripts/exp/imix_v6-0.erf index 2dd16e111f11d7973d5cdbfdb43b6cd80509835c..d52d8541d992f0e1e7a32208a7614ff094241d06 100644 GIT binary patch delta 1303 zcmYMyF=&%P6u@!secx9F6;Trj2!TK(CAN-kE}aUdLqJ^OP)NQ8G0Bo@2MIzQDwv|- zAWN2j1Wc`=;pTv3$&w{YmZ;RBLP4@*5)Am>-SypexsSdd_x}BOdh zZCOtgXnaSH7hPFO76|BRKq#3>6^IyULJZ|vx*> zHjLPGV#|na7CTn#ve>htVsT)_AvyT~*NG?kZ~b%hdSuYCLnj8EI&@~xQ%27$dd}$F uq6xeLysGJrXdcr4L#gx75)PxRhJzA delta 1582 zcmYM!aY&SB90%~;=Y3v{btrf0?Lab(yWCw?3kPH5(ajM#cFwHGM3CCuNli~<-nNP? zcEMfj&X#+aW6G&*HFnWNc`HUB8%}l(uaU)sY2uYe+^AzisNp>9d7t0I^Zs=|p6B5E z;rD!bfB6Alx`sz;ib$&PP4!$+9HGSp)nPH`;FVJc>dESQFN%58YbBo`d?UNHi9Fcg zl^dQ|NTke%+dsoT^|~Q|kg=6~Xl=oEWxidF<_C~GmHC~#SMI~1kG}0v+f4K%X1GYU zI((S^28p}Ki(Su8hez822sd16iK-Qr!W`V;*x#c?Vq@X%UiEqjy|fQI`n6D;{QA`) z5-s!M#hvn1mWo5g|HMg~)r(^{=Z0A>b`4Id#9i*iE1NHmv0!W(i;j~DhZhDd`NsFB z5-d6C@+Bd8adzJ{OAbvqXCQf?**?dTT{Y$uOFsNadJM@cQ<*eNHnq%VAo*rpVwoj( z+#k%cWF_Q}Ac<^qc=%LXDPd_X18M=>Di27MGGV%?yR zVn)!7y!_XS5$ne2e}$!pbz}0&bvAmfb))snGdp742%7)ej-VU1b-z{89NLYA^8-!< z-FUI_^J-wgq%rz(KivzAs((Fh&NvvUs|Uu5K-D46IREpOCScg&1xJA4d}qze8L5h= z#|5LEGx|m*I)QQUjaV0FwEl4+2s?mDdz8GNJ`Mw8^zsK$&Y0Zweh)A@Y`c0nW3|K9 z4~&6E(-1IjEoZNA#^L$DEB!J=Ae>BM% zZ$EWU17qpWw`MrwM5%QS7zM8wQ^0UsSzY3cJKgEDU}QKWY#d((M)g;HSOm8vDtQucfuvvy`JiNQPSZ3Aue{F4(%&KADF>j^U pS~Xs8zHOI9HDstpY|pJq8c3^g@4FLD8LIK@UTw9^8VVC##!G8`GfV&g diff --git a/scripts/exp/ipv4_vlan-0-ex.erf b/scripts/exp/ipv4_vlan-0-ex.erf index 6f75b99b3e3323db6e36d0e28d1f465e46c914c4..435d8c320a692a9da2844c0eae8a69d75ae01a9c 100755 GIT binary patch delta 752 zcmY+=uS*0`5C?GH?%RF8?!;g*h+)eW!La@jR&U`U+%Q zK6t*?9Mte_qSEl9O1Q8Er?&4W)K@oS+Dc3KbcM<=MV=*Gdg|}oN4kVVO&u{jOK=%= z> zS9F4;)b>T7J-wn6B&D_!(lgTkLwZ8uV5DcH7bGRz3epSG3oafx4>+fd>Xzc#nA z#3g?3kERoso9^#x^IJ8)Rp!^`R#Xg}xxbN1{My_a5|{WzZxWaIMQ<)Q-QQQ{w`P88 z%rAPAxWq4dleok$dXu=sFM4yi>HZGQ?~M7KVSdq@#3g=hZWD=1{GPPlaELN{%f3VC zxCA%)C3CxKy_Mj`?HCm<-*&AxiA((2+=ddD__eu> zB`)!c`{r`f_aWXP^8W|)R?Y7%a*1D?TSMX!zvxZk62Iup<)-_aec#ZV#3g>wo5Ur4 z(VN62e$kuDP4_pxzhr;Wo5Ur4(VN62e$iVkzqfcVh=-Eg=$Fr}C4DdPi{2zI@r&Lh zF7fbq=~2(+rtd@ceLMH`^g!YgzaKBWA4*)}_vV-DV~I=rR&W2ExZL!8h#r+vTSFn|{GvCBOZ=iYiA(&VH56PKI55AhC>_rc~?%;onMxx}x{ts!xVUz=M? z;u62#w>H`?H{IXt`(|_NN?hU>y-8f+7rjYb;upQS+;o5A`%Cs0y-8f+7rjYb;upQu z^Lxv_ZzZ|WFP~dW`d;D}_f6swzqoG_mv}&LE;oH2O5Hb!OZ=iYiA(&VH;GI9qBobD zz7O#Zk@w+{^){d1TjUbI&+NWQT;lhl-8YF#{C>6j=5o{h&AxAU?7m4{;@9TZleomM z&21oYiC>%B(B-E48{c2Dzc#nA#3g=hZWD=1{Gzvo{NA$fTS;#8OXhZbcC#gYFY){4 z$x2(|62F(vzwAm};^D{V^`6U3--qn`cJJ2yw!|fVZEiz}OZ?j0#uAtKwYg1PZu&mN zJ4D_Gn_ID%-&^Dozc#mH5|{WzZxWaIMQ<)Q-QVo{hTbGD@r&LhF7b=rBrfrb-dt|F hzw!Mg`-|QrF7b=rBrfrb-j?!v%f4?VxzR6~+kc1+Iy?XX diff --git a/scripts/exp/ipv4_vlan-0.erf b/scripts/exp/ipv4_vlan-0.erf index 6f75b99b3e3323db6e36d0e28d1f465e46c914c4..435d8c320a692a9da2844c0eae8a69d75ae01a9c 100644 GIT binary patch delta 752 zcmY+=uS*0`5C?GH?%RF8?!;g*h+)eW!La@jR&U`U+%Q zK6t*?9Mte_qSEl9O1Q8Er?&4W)K@oS+Dc3KbcM<=MV=*Gdg|}oN4kVVO&u{jOK=%= z> zS9F4;)b>T7J-wn6B&D_!(lgTkLwZ8uV5DcH7bGRz3epSG3oafx4>+fd>Xzc#nA z#3g?3kERoso9^#x^IJ8)Rp!^`R#Xg}xxbN1{My_a5|{WzZxWaIMQ<)Q-QQQ{w`P88 z%rAPAxWq4dleok$dXu=sFM4yi>HZGQ?~M7KVSdq@#3g=hZWD=1{GPPlaELN{%f3VC zxCA%)C3CxKy_Mj`?HCm<-*&AxiA((2+=ddD__eu> zB`)!c`{r`f_aWXP^8W|)R?Y7%a*1D?TSMX!zvxZk62Iup<)-_aec#ZV#3g>wo5Ur4 z(VN62e$kuDP4_pxzhr;Wo5Ur4(VN62e$iVkzqfcVh=-Eg=$Fr}C4DdPi{2zI@r&Lh zF7fbq=~2(+rtd@ceLMH`^g!YgzaKBWA4*)}_vV-DV~I=rR&W2ExZL!8h#r+vTSFn|{GvCBOZ=iYiA(&VH56PKI55AhC>_rc~?%;onMxx}x{ts!xVUz=M? z;u62#w>H`?H{IXt`(|_NN?hU>y-8f+7rjYb;upQS+;o5A`%Cs0y-8f+7rjYb;upQu z^Lxv_ZzZ|WFP~dW`d;D}_f6swzqoG_mv}&LE;oH2O5Hb!OZ=iYiA(&VH;GI9qBobD zz7O#Zk@w+{^){d1TjUbI&+NWQT;lhl-8YF#{C>6j=5o{h&AxAU?7m4{;@9TZleomM z&21oYiC>%B(B-E48{c2Dzc#nA#3g=hZWD=1{Gzvo{NA$fTS;#8OXhZbcC#gYFY){4 z$x2(|62F(vzwAm};^D{V^`6U3--qn`cJJ2yw!|fVZEiz}OZ?j0#uAtKwYg1PZu&mN zJ4D_Gn_ID%-&^Dozc#mH5|{WzZxWaIMQ<)Q-QVo{hTbGD@r&LhF7b=rBrfrb-dt|F hzw!Mg`-|QrF7b=rBrfrb-j?!v%f4?VxzR6~+kc1+Iy?XX diff --git a/scripts/exp/ipv6-0-ex.erf b/scripts/exp/ipv6-0-ex.erf index 8293b1097c0b3a3900e712eca3b7deae18fa681e..d50f1704898c88c444d7c9378627d12841d0db3f 100755 GIT binary patch delta 752 zcmX}pt4;$^5C-6Edv?#QR|0PUz5?C=9HN4HL=nwtQUv%4`T)%YU(tFJf=AFdD6XOc zd<~v|W_QQTWp`%sW%oFlPu^C3c`&s0QyOOG{WRQWv}za{$0_xihIYsYYv{VQr+Z`Q zyuIgn(~)_4LjKGQ{U8spcGsQC`WG^Wk`&>Wk{b9DGrHt!1A6 E0lb#q4FCWD delta 879 zcmX}nJ7^S96vlC8_rCAG!A4UEK2lpO!Ab(Alr4M_D^my?XJHW)EaO0gpa|iR$`uui zA~u2!f*_J2^%}uKS+r5yMp#jM&-n(Y+RNh~vhaz)#fRA2sdVXWw5Om+3@pQ)nt zYATD0ro4v5oTf_(i>{`vIu<=mOB##5rt1wXGEGNJ(a?0ZSu`~5@<|$e&lU|$+pVHu zHu)tIGqm0=5{A0INSMvWk`&>Wk{b9DGrHt!1A6 E0lb#q4FCWD delta 879 zcmX}nJ7^S96vlC8_rCAG!A4UEK2lpO!Ab(Alr4M_D^my?XJHW)EaO0gpa|iR$`uui zA~u2!f*_J2^%}uKS+r5yMp#jM&-n(Y+RNh~vhaz)#fRA2sdVXWw5Om+3@pQ)nt zYATD0ro4v5oTf_(i>{`vIu<=mOB##5rt1wXGEGNJ(a?0ZSu`~5@<|$e&lU|$+pVHu zHu)tIGqm0=5{A0INSMvGLf2&~G&@c%z=ruL0v2Trr>(&PD zwTAQdhMw0Qejc8%e<=-r*oPRq>&`g-jh*6`y(+%yZD5b*mp;cQCsllneeN|b_)!t| zJRN9rkEhQm!(V14dHlHqib(|O#j z)@G2I0uBRq;r-4ODu=P9y698Aa=a)ncXT@QR1+_U#LJnN3lGyZ&j`;5&m^8Q#R{#J2 delta 875 zcmX}nJ!lj`7{+n-c4ua1=5k+P0-8ebBelpP!9oO6$`VEZ3FQT0wQ^%gn^&|S@GWG7nb{^57lBvrdFAO94;4>9o z{XLFoJwA0oa6}$#V1x+D6X->LcvAP zLcvAfLcv9Dq2OX@q2OX{p^yzH3LK!=uWu#}idPTzrcM-#^Do;DiXZP!_Z$?rI^XX( zC^*O+6dVj46kLoQ6kJq16kP1{P{@RbLMA*Evf-hS4G)EEcqnAULm?X;3fb^b$VOEZ HIEdmetVB9L diff --git a/scripts/exp/ipv6_vlan-0.erf b/scripts/exp/ipv6_vlan-0.erf index 5ed0b86625ea9faec8236f702abea35178a4bc21..8ca5f09bacea9d85f313647ad3e9d1693c9b4f50 100644 GIT binary patch delta 750 zcmX}ptxf|$5C`yVyLbE5PXb9F0DJ|!0XRej^@t*xZE^_k74!iv6MRMSBm|FuHz=;6 zg8GWqGc$KPW@dJC|H<#}_S5GLf2&~G&@c%z=ruL0v2Trr>(&PD zwTAQdhMw0Qejc8%e<=-r*oPRq>&`g-jh*6`y(+%yZD5b*mp;cQCsllneeN|b_)!t| zJRN9rkEhQm!(V14dHlHqib(|O#j z)@G2I0uBRq;r-4ODu=P9y698Aa=a)ncXT@QR1+_U#LJnN3lGyZ&j`;5&m^8Q#R{#J2 delta 875 zcmX}nJ!lj`7{+n-c4ua1=5k+P0-8ebBelpP!9oO6$`VEZ3FQT0wQ^%gn^&|S@GWG7nb{^57lBvrdFAO94;4>9o z{XLFoJwA0oa6}$#V1x+D6X->LcvAP zLcvAfLcv9Dq2OX@q2OX{p^yzH3LK!=uWu#}idPTzrcM-#^Do;DiXZP!_Z$?rI^XX( zC^*O+6dVj46kLoQ6kJq16kP1{P{@RbLMA*Evf-hS4G)EEcqnAULm?X;3fb^b$VOEZ HIEdmetVB9L diff --git a/scripts/exp/limit_multi_pkt-0.erf b/scripts/exp/limit_multi_pkt-0.erf index b6487e6f28692ec9048e94d960ad7bdf110fb668..4cb6989100486a9f38417b7b6463c78ad6b852f6 100644 GIT binary patch literal 30944 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 diff --git a/scripts/exp/limit_single_pkt-0-ex.erf b/scripts/exp/limit_single_pkt-0-ex.erf index e2725b9e38158f32f3e4092857529748a7834169..344a25d00bdba88dac005d6f9ff25f35114a7eb0 100755 GIT binary patch delta 459 zcmX|+F-k-+5I{+OCdnjU@B((W+lZCo3B)SwkA=csz#AxRFCsFf2wvcW9>60ATiV!J z*a-F_I5WYN6Xxa3d))utds+jnj5GG`ywDq*(zbPGpe-}ewV#KLKcK^~)RloQY@yH4 zb{y>t6WzzQbBt}r(UqI51zJEEcF%6<2bXa9{82&v-#BN0-k|{hI|ExP&o`b4PcJ-p zItoSiy~+ge^u=!icvi~JLu4S(D-VHAumOS1GXG-p1UW(P4y*>g#YRzUV3a^xBfG1K zte)%~#jQXTw-P9BB~Ws0MV42C>}CQ*t^~I1Bu)jB+@T@qKRosDq~WQBXARFiJooV2 R!?T9x7CvhD*uzJ5mp}Mhg027n delta 572 zcmXxfze>YU6b5iia&GQTQitxYE|R5)C@Q!)NT<+t@&yF(2?WXNA1DU|k%BJ}aB=Jt z_y_6|ia2OTDYywPdd_##?c{vtVT`H&u`SD-|MYB41K%|~mz{QvLeMolvc4Phv+T4RbJzK9 z3|4!5QN|4mGguFuk6N|`$ttj5&3-m=3zmcfyI_@e!K&xb>6bU`bj#uv+qN(y%at)tfs1S|>b1T0B|6f8;e6fCW# gU}-l6OS>sp+D*aIZU&ZiGqALqfu-H7VPRI*KfheaPyhe` diff --git a/scripts/exp/limit_single_pkt-0.erf b/scripts/exp/limit_single_pkt-0.erf index e2725b9e38158f32f3e4092857529748a7834169..344a25d00bdba88dac005d6f9ff25f35114a7eb0 100644 GIT binary patch delta 459 zcmX|+F-k-+5I{+OCdnjU@B((W+lZCo3B)SwkA=csz#AxRFCsFf2wvcW9>60ATiV!J z*a-F_I5WYN6Xxa3d))utds+jnj5GG`ywDq*(zbPGpe-}ewV#KLKcK^~)RloQY@yH4 zb{y>t6WzzQbBt}r(UqI51zJEEcF%6<2bXa9{82&v-#BN0-k|{hI|ExP&o`b4PcJ-p zItoSiy~+ge^u=!icvi~JLu4S(D-VHAumOS1GXG-p1UW(P4y*>g#YRzUV3a^xBfG1K zte)%~#jQXTw-P9BB~Ws0MV42C>}CQ*t^~I1Bu)jB+@T@qKRosDq~WQBXARFiJooV2 R!?T9x7CvhD*uzJ5mp}Mhg027n delta 572 zcmXxfze>YU6b5iia&GQTQitxYE|R5)C@Q!)NT<+t@&yF(2?WXNA1DU|k%BJ}aB=Jt z_y_6|ia2OTDYywPdd_##?c{vtVT`H&u`SD-|MYB41K%|~mz{QvLeMolvc4Phv+T4RbJzK9 z3|4!5QN|4mGguFuk6N|`$ttj5&3-m=3zmcfyI_@e!K&xb>6bU`bj#uv+qN(y%at)tfs1S|>b1T0B|6f8;e6fCW# gU}-l6OS>sp+D*aIZU&ZiGqALqfu-H7VPRI*KfheaPyhe` diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp index 87f3f7ca..4c04dde9 100755 --- a/src/bp_gtest.cpp +++ b/src/bp_gtest.cpp @@ -263,7 +263,7 @@ TEST_F(basic, limit_single_pkt) { EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } -/*TEST_F(basic, limit_multi_pkt) { +TEST_F(basic, limit_multi_pkt) { CTestBasic t1; CParserOption * po =&CGlobalInfo::m_options; @@ -273,7 +273,7 @@ TEST_F(basic, limit_single_pkt) { po->out_file ="exp/limit_multi_pkt"; bool res=t1.init(); EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; -} */ +} TEST_F(basic, imix) { @@ -287,6 +287,18 @@ TEST_F(basic, imix) { EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } +TEST_F(basic, imix_fast) { + + CTestBasic t1; + CParserOption * po =&CGlobalInfo::m_options; + po->preview.setVMode(3); + po->preview.setFileWrite(true); + po->cfg_file ="cap2/imix_64_fast.yaml"; + po->out_file ="exp/imix_64_fast"; + bool res=t1.init(); + EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; +} + TEST_F(basic, dns) { diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 0725a437..72eb91ba 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -3475,8 +3475,12 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id, 0 , socket_id); - m_tw.Create(TW_BUCKETS,3); - + RC_HTW_t tw_res=m_tw.Create(TW_BUCKETS,3); + if (tw_res != RC_HTW_OK){ + CHTimerWheelErrorStr err(tw_res); + printf("ERROR %-30s - %s \n",err.get_str(),err.get_help_str()); + exit(1); + } m_node_gen.Create(this); m_flow_id_to_node_lookup.Create(); @@ -3542,19 +3546,6 @@ FORCE_NO_INLINE void CFlowGenListPerThread::handler_defer_job(CGenNode *p){ } } -FORCE_NO_INLINE void CFlowGenListPerThread::handler_defer_job_flush(void){ - /* flush the pending job of free ports */ - if (m_tcp_dpc) { - handler_defer_job((CGenNode *)m_tcp_dpc); - free_node((CGenNode *)m_tcp_dpc); - m_tcp_dpc=0; - } - if (m_udp_dpc) { - handler_defer_job((CGenNode *)m_udp_dpc); - free_node((CGenNode *)m_udp_dpc); - m_udp_dpc=0; - } -} void CFlowGenListPerThread::defer_client_port_free(bool is_tcp, @@ -3767,7 +3758,10 @@ template inline void CFlowGenListPerThread::on_flow_tick(CGenNode *node){ #ifdef TREX_SIM - node->m_time=m_cur_time_sec; + /* for sim, we need to update the node from tick time*/ + if ( likely (!node->is_repeat_flow() ) ){ + node->m_time=m_cur_time_sec; + } #endif #ifdef _DEBUG m_node_gen.update_stats(node); @@ -3777,22 +3771,22 @@ inline void CFlowGenListPerThread::on_flow_tick(CGenNode *node){ if ( likely (!node->is_repeat_flow()) ) { if ( likely (!node->is_last_in_flow()) ) { m_tw.timer_start(&node->m_tmr,node->update_next_pkt_in_flow_tw() ); - }else{ - free_last_flow_node( node); + }else{ + free_last_flow_node(node); } }else{ /* repeatable flow, we need to stop it in case of repeat */ if ( node->is_last_in_flow() ) { if ( TEARDOWN == false ){ - node->m_time=m_cur_time_sec; /* update the node time as we schedule it */ - reschedule_flow(node); + reschedule_flow(node); }else{ - free_last_flow_node( node); + free_last_flow_node(node); } }else{ - m_tw.timer_start(&node->m_tmr,node->update_next_pkt_in_flow_tw() ); + /* need to update both accurate time and bucket time in this case update_next_pkt_in_flow_both() for reschedule to be accurate */ + m_tw.timer_start(&node->m_tmr,node->update_next_pkt_in_flow_both() ); } } } @@ -3809,6 +3803,19 @@ inline void CFlowGenListPerThread::on_flow_tick(CGenNode *node){ #define UNSAFE_CONTAINER_OF_POP GCC_DIAG_ON() +static void tw_free_node(void *userdata, + CHTimerObj *tmr){ + CFlowGenListPerThread * thread=(CFlowGenListPerThread * )userdata; + UNSAFE_CONTAINER_OF_PUSH; + CGenNode * node=unsafe_container_of(node,tmr,CGenNode,m_tmr); + UNSAFE_CONTAINER_OF_POP; + if (node->is_flow_node()) { + /* this is a flow*/ + thread->free_last_flow_node(node); + }else{ + thread->free_node(node); + } +} static void tw_on_tick_per_thread_cb_always(void *userdata, @@ -3834,6 +3841,26 @@ void tw_on_tick_per_thread_cb(void *userdata, } +FORCE_NO_INLINE void CFlowGenListPerThread::handler_defer_job_flush(void){ + + /* free the objects letf in TW */ + m_tw.detach_all((void *)this,tw_free_node); + + /* flush the pending job of free ports */ + if (m_tcp_dpc) { + handler_defer_job((CGenNode *)m_tcp_dpc); + free_node((CGenNode *)m_tcp_dpc); + m_tcp_dpc=0; + } + if (m_udp_dpc) { + handler_defer_job((CGenNode *)m_udp_dpc); + free_node((CGenNode *)m_udp_dpc); + m_udp_dpc=0; + } +} + + + inline bool CNodeGenerator::do_work_stl(CGenNode * node, CFlowGenListPerThread * thread, bool on_terminate){ @@ -3883,7 +3910,6 @@ inline bool CNodeGenerator::do_work_both(CGenNode * node, /* PKT */ m_p_queue.pop(); thread->on_flow_tick(node); - //printf(" MOVE from PKT->TW\n"); }else{ if ((type == CGenNode::FLOW_FIF)) { /* callback to our method */ @@ -3968,6 +3994,7 @@ inline int CNodeGenerator::teardown(CFlowGenListPerThread * thread, }else{ // free the left other thread->handler_defer_job_flush(); + } return (0); } @@ -4211,7 +4238,7 @@ void CNodeGenerator::handle_flow_pkt(CGenNode *node, CFlowGenListPerThread *thre } m_p_queue.pop(); if ( node->is_last_in_flow() ) { - thread->free_last_flow_node( node); + thread->free_last_flow_node(node); } else { node->update_next_pkt_in_flow_as(); m_p_queue.push(node); @@ -4510,7 +4537,7 @@ void CFlowGenListPerThread::terminate_nat_flows(CGenNode *p){ } else { m_flow_id_to_node_lookup.remove_no_lookup(p->get_short_fid() & NAT_FLOW_ID_MASK_IP_ID); } - free_last_flow_node( p); + free_last_flow_node(p); } diff --git a/src/bp_sim.h b/src/bp_sim.h index e8a37f6f..a41349d0 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -1498,6 +1498,14 @@ public: } void free_base(); + + bool is_flow_node(){ + if ((m_type == FLOW_PKT) || (m_type == FLOW_PKT_NAT)) { + return (true); + }else{ + return (false); + } + } }; @@ -1557,6 +1565,9 @@ public: /* update the node time for accurate scheduler */ inline void update_next_pkt_in_flow_as(void); + inline uint32_t update_next_pkt_in_flow_both(void); + + inline void reset_pkt_in_flow(void); inline uint8_t get_plugin_id(void){ return ( m_template_info->m_plugin_id); @@ -4108,6 +4119,17 @@ inline void CGenNode::update_next_pkt_in_flow_as(void){ m_pkt_info = m_flow_info->GetPacket((pkt_index-1)); } + +inline uint32_t CGenNode::update_next_pkt_in_flow_both(void){ + m_time += m_pkt_info->m_pkt_indication.m_cap_ipg; + uint32_t dticks = m_pkt_info->m_pkt_indication.m_ticks; + uint32_t pkt_index = m_pkt_info->m_pkt_indication.m_packet->pkt_cnt; + pkt_index++; + m_pkt_info = m_flow_info->GetPacket((pkt_index-1)); + return (dticks); +} + + inline uint32_t CGenNode::update_next_pkt_in_flow_tw(void){ uint32_t dticks = m_pkt_info->m_pkt_indication.m_ticks; diff --git a/src/gtest/bp_timer_gtest.cpp b/src/gtest/bp_timer_gtest.cpp index c0779868..5185da87 100644 --- a/src/gtest/bp_timer_gtest.cpp +++ b/src/gtest/bp_timer_gtest.cpp @@ -189,6 +189,17 @@ void my_test_on_tick_cb7(void *userdata,CHTimerObj *tmr){ lp->timer_start(tmr,9); } +void my_test_on_tick_cb_free(void *userdata,CHTimerObj *tmr){ + + + //CHTimerWheel * lp=(CHTimerWheel *)userdata; + #pragma GCC diagnostic ignored "-Winvalid-offsetof" + CMyTestObject *lpobj=(CMyTestObject *)((uint8_t*)tmr-offsetof (CMyTestObject,m_timer)); + #pragma GCC diagnostic pop + printf(" [event %d ]",lpobj->m_id); + delete lpobj; +} + TEST_F(gt_r_timer, timer7) { @@ -593,3 +604,53 @@ TEST_F(gt_r_timer, timer16) { test.Delete(); } + +/* test free of iterator */ +TEST_F(gt_r_timer, timer17) { + + CHTimerWheel timer; + + CMyTestObject * tmr1; + tmr1 = new CMyTestObject(); + tmr1->m_id=12; + + CMyTestObject * tmr2; + tmr2 = new CMyTestObject(); + tmr2->m_id=13; + + CMyTestObject * tmr3; + tmr3 = new CMyTestObject(); + tmr3->m_id=14; + + + EXPECT_EQ( timer.Create(4,4),RC_HTW_OK); + timer.timer_start(&tmr1->m_timer,80); + timer.timer_start(&tmr2->m_timer,1); + timer.timer_start(&tmr3->m_timer,0); + + timer.detach_all((void *)&timer,my_test_on_tick_cb_free); + EXPECT_EQ( timer.Delete(),RC_HTW_OK); +} + + +TEST_F(gt_r_timer, timer18) { + + RC_HTW_t res[]={ + RC_HTW_OK, + RC_HTW_ERR_NO_RESOURCES, + RC_HTW_ERR_TIMER_IS_ON, + RC_HTW_ERR_NO_LOG2, + RC_HTW_ERR_MAX_WHEELS, + RC_HTW_ERR_NOT_ENOUGH_BITS + }; + + int i; + for (i=0; iis_self()) { + first = lp->m_next; + first->detach(); + m_total_events++; + assert(cb); + cb(userdata,(CHTimerObj *)first); + } + } + return (m_total_events); +} + RC_HTW_t CHTimerOneWheel::timer_stop(CHTimerObj *tmr){ if ( tmr->is_running() ) { tmr->detach(); @@ -107,11 +131,27 @@ void CHTimerOneWheel::dump_link_list(uint32_t bucket_index, } -void CHTimerWheel::on_tick(void *userdata,htw_on_tick_cb_t cb){ - +void CHTimerWheel::detach_all(void *userdata,htw_on_tick_cb_t cb){ + #ifndef _DEBUG + if (m_total_events==0) { + return; + } + #endif int i; + uint32_t res=0; + for (i=0;idetach_all(userdata,cb); + assert(m_total_events>=res); + m_total_events -=res; + } + assert(m_total_events==0); +} +void CHTimerWheel::on_tick(void *userdata,htw_on_tick_cb_t cb){ + + int i; for (i=0;iis_running() ){ return( RC_HTW_ERR_TIMER_IS_ON); } @@ -146,6 +201,8 @@ public: RC_HTW_t timer_stop (CHTimerObj *tmr); + uint32_t detach_all(void *userdata,htw_on_tick_cb_t cb); + inline bool check_timer_tick_cycle(){ return (m_tick_done); } @@ -247,6 +304,7 @@ public: RC_HTW_t Delete(); + inline RC_HTW_t timer_start(CHTimerObj *tmr, htw_ticks_t ticks){ m_total_events++; @@ -265,7 +323,9 @@ public: bool is_any_events_left(){ return(m_total_events>0?true:false); } - + + /* iterate all, detach and call the callback */ + void detach_all(void *userdata,htw_on_tick_cb_t cb); private: diff --git a/src/h_timer_w.h b/src/h_timer_w.h deleted file mode 100644 index 552c7423..00000000 --- a/src/h_timer_w.h +++ /dev/null @@ -1,533 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 indent-tabs-mode: nil -*- */ -// -// Copyright 2016 Juho Snellman, released under a MIT license (see -// LICENSE). -// -// A timer queue which allows events to be scheduled for execution -// at some later point. Reasons you might want to use this implementation -// instead of some other are: -// -// - A single-file C++11 implementation with no external dependencies. -// - Optimized for high occupancy rates, on the assumption that the -// utilization of the timer queue is proportional to the utilization -// of the system as a whole. When a tradeoff needs to be made -// between efficiency of one operation at a low occupancy rate and -// another operation at a high rate, we choose the latter. -// - Tries to minimize the cost of event rescheduling or cancelation, -// on the assumption that a large percentage of events will never -// be triggered. The implementation avoids unnecessary work when an -// event is rescheduled, and provides a way for the user specify a -// range of acceptable execution times instead of just an exact one. -// - Facility for limiting the number of events to execute on a -// single invocation, to allow fine grained interleaving of timer -// processing and application logic. -// - An interface that at least the author finds convenient. -// -// The exact implementation strategy is a hierarchical timer -// wheel. A timer wheel is effectively a ring buffer of linked lists -// of events, and a pointer to the ring buffer. As the time advances, -// the pointer moves forward, and any events in the ring buffer slots -// that the pointer passed will get executed. -// -// A hierarchical timer wheel layers multiple timer wheels running at -// different resolutions on top of each other. When an event is -// scheduled so far in the future than it does not fit the innermost -// (core) wheel, it instead gets scheduled on one of the outer -// wheels. On each rotation of the inner wheel, one slot's worth of -// events are promoted from the second wheel to the core. On each -// rotation of the second wheel, one slot's worth of events is -// promoted from the third wheel to the second, and so on. -// -// The basic usage is to create a single TimerWheel object and -// multiple TimerEvent or MemberTimerEvent objects. The events are -// scheduled for execution using TimerWheel::schedule() or -// TimerWheel::schedule_in_range(), or unscheduled using the event's -// cancel() method. -// -// Example usage: -// -// typedef std::function Callback; -// TimerWheel timers; -// int count = 0; -// TimerEvent timer([&count] () { ++count; }); -// -// timers.schedule(&timer, 5); -// timers.advance(4); -// assert(count == 0); -// timers.advance(1); -// assert(count == 1); -// -// timers.schedule(&timer, 5); -// timer.cancel(); -// timers.advance(4); -// assert(count == 1); -// -// To tie events to specific member functions of an object instead of -// a callback function, use MemberTimerEvent instead of TimerEvent. -// For example: -// -// class Test { -// public: -// Test() : inc_timer_(this) { -// } -// void start(TimerWheel* timers) { -// timers->schedule(&inc_timer_, 10); -// } -// void on_inc() { -// count_++; -// } -// int count() { return count_; } -// private: -// MemberTimerEvent inc_timer_; -// int count_ = 0; -// }; - -#ifndef RATAS_TIMER_WHEEL_H -#define RATAS_TIMER_WHEEL_H - -#include -#include -#include -#include -#include -#include - -typedef uint64_t tick_t; - -class TimerWheelSlot; -class TimerWheel; - -// An abstract class representing an event that can be scheduled to -// happen at some later time. -struct TimerEventInterface { -public: - // Unschedule this event. It's safe to cancel an event that is inactive. - inline void cancel(); - - // Return true iff the event is currently scheduled for execution. - bool active() const { - return slot_ != NULL; - } - - // Return the absolute tick this event is scheduled to be executed on. - tick_t scheduled_at() const { return scheduled_at_; } - -private: - TimerEventInterface(const TimerEventInterface& other) = delete; - TimerEventInterface& operator=(const TimerEventInterface& other) = delete; - friend TimerWheelSlot; - friend TimerWheel; - - - void set_scheduled_at(tick_t ts) { scheduled_at_ = ts; } - // Move the event to another slot. (It's safe for either the current - // or new slot to be NULL). - inline void relink(TimerWheelSlot* slot); - -private: - /* one CACHELINE 32 byte in 64bit processor */ - - tick_t scheduled_at_; - // The slot this event is currently in (NULL if not currently scheduled). - TimerWheelSlot* slot_ = NULL; - // The events are linked together in the slot using an internal - // doubly-linked list; this iterator does double duty as the - // linked list node for this event. - TimerEventInterface* next_ = NULL; - TimerEventInterface* prev_ = NULL; -}; - -#if 0 -// An event that takes the callback (of type CBType) to execute as -// a constructor parameter. -template -class TimerEvent : public TimerEventInterface { -public: - explicit TimerEvent(const CBType& callback) - : callback_(callback) { - } - - void execute() { - callback_(); - } - -private: - TimerEvent(const TimerEvent& other) = delete; - TimerEvent& operator=(const TimerEvent& other) = delete; - CBType callback_; -}; - -// An event that's specialized with a (static) member function of class T, -// and a dynamic instance of T. Event execution causes an invocation of the -// member function on the instance. -template -class MemberTimerEvent : public TimerEventInterface { -public: - MemberTimerEvent(T* obj) : obj_(obj) { - } - - virtual void execute () { - (obj_->*MFun)(); - } - -private: - T* obj_; -}; - -#endif - -// Purely an implementation detail. -class TimerWheelSlot { -public: - TimerWheelSlot() { - } - -private: - // Return the first event queued in this slot. - const TimerEventInterface* events() const { return events_; } - // Deque the first event from the slot, and return it. - TimerEventInterface* pop_event() { - auto event = events_; - events_ = event->next_; - if (events_) { - events_->prev_ = NULL; - } - event->next_ = NULL; - event->slot_ = NULL; - return event; - } - - TimerWheelSlot(const TimerWheelSlot& other) = delete; - TimerWheelSlot& operator=(const TimerWheelSlot& other) = delete; - friend TimerEventInterface; - friend TimerWheel; - - // Doubly linked (inferior) list of events. - TimerEventInterface* events_ = NULL; -}; - -// A TimerWheel is the entity that TimerEvents can be scheduled on -// for execution (with schedule() or schedule_in_range()), and will -// eventually be executed once the time advances far enough with the -// advance() method. - -class TimerWheel { -public: - bool Create(tick_t now = 0){ - for (int i = 0; i < NUM_LEVELS; ++i) { - now_[i] = now >> (WIDTH_BITS * i); - } - ticks_pending_ = 0; - } - void Delete(){ - } - - // Advance the TimerWheel by the specified number of ticks, and execute - // any events scheduled for execution at or before that time. The - // number of events executed can be restricted using the max_execute - // parameter. If that limit is reached, the function will return false, - // and the excess events will be processed on a subsequent call. - // - // - It is safe to cancel or schedule events from within event callbacks. - // - During the execution of the callback the observable event tick will - // be the tick it was scheduled to run on; not the tick the clock will - // be advanced to. - // - Events will happen in order; all events scheduled for tick X will - // be executed before any event scheduled for tick X+1. - // - // Delta should be non-0. The only exception is if the previous - // call to advance() returned false. - // - // advance() should not be called from an event callback. - inline bool advance(tick_t delta, - size_t max_execute=std::numeric_limits::max(), - int level = 0); - - // Schedule the event to be executed delta ticks from the current time. - // The delta must be non-0. - inline void schedule(TimerEventInterface* event, tick_t delta); - - // Schedule the event to happen at some time between start and end - // ticks from the current time. The actual time will be determined - // by the TimerWheel to minimize rescheduling and promotion overhead. - // Both start and end must be non-0, and the end must be greater than - // the start. - inline void schedule_in_range(TimerEventInterface* event, - tick_t start, tick_t end); - - // Return the current tick value. Note that if the time increases - // by multiple ticks during a single call to advance(), during the - // execution of the event callback now() will return the tick that - // the event was scheduled to run on. - tick_t now() const { return now_[0]; } - - // Return the number of ticks remaining until the next event will get - // executed. If the max parameter is passed, that will be the maximum - // tick value that gets returned. The max parameter's value will also - // be returned if no events have been scheduled. - // - // Will return 0 if the wheel still has unprocessed events from the - // previous call to advance(). - inline tick_t ticks_to_next_event(tick_t max = std::numeric_limits::max(), - int level = 0); - -private: - TimerWheel(const TimerWheel& other) = delete; - TimerWheel& operator=(const TimerWheel& other) = delete; - - // This handles the actual work of executing event callbacks and - // recursing to the outer wheels. - inline bool process_current_slot(tick_t now, size_t max_execute, int level); - - static const int WIDTH_BITS = 8; - static const int NUM_LEVELS = (64 + WIDTH_BITS - 1) / WIDTH_BITS; - static const int MAX_LEVEL = NUM_LEVELS - 1; - static const int NUM_SLOTS = 1 << WIDTH_BITS; - // A bitmask for looking at just the bits in the timestamp relevant to - // this wheel. - static const int MASK = (NUM_SLOTS - 1); - - // The current timestamp for this wheel. This will be right-shifted - // such that each slot is separated by exactly one tick even on - // the outermost wheels. - tick_t now_[NUM_LEVELS]; - // We've done a partial tick advance. This is how many ticks remain - // unprocessed. - tick_t ticks_pending_; - TimerWheelSlot slots_[NUM_LEVELS][NUM_SLOTS]; -}; - -// Implementation - -inline void TimerEventInterface::relink(TimerWheelSlot* new_slot) { - if (new_slot == slot_) { - return; - } - - // Unlink from old location. - if (slot_) { - auto prev = prev_; - auto next = next_; - if (next) { - next->prev_ = prev; - } - if (prev) { - prev->next_ = next; - } else { - // Must be at head of slot. Move the next item to the head. - slot_->events_ = next; - } - } - - // Insert in new slot. - { - if (new_slot) { - auto old = new_slot->events_; - next_ = old; - if (old) { - old->prev_ = this; - } - new_slot->events_ = this; - } else { - next_ = NULL; - } - prev_ = NULL; - } - slot_ = new_slot; -} - -inline void TimerEventInterface::cancel() { - // It's ok to cancel a event that's not scheduled. - if (!slot_) { - return; - } - - relink(NULL); -} - -inline bool TimerWheel::advance(tick_t delta, size_t max_events, int level) { - if (ticks_pending_) { - if (level == 0) { - // Continue collecting a backlog of ticks to process if - // we're called with non-zero deltas. - ticks_pending_ += delta; - } - // We only partially processed the last tick. Process the - // current slot, rather incrementing like advance() normally - // does. - tick_t now = now_[level]; - if (!process_current_slot(now, max_events, level)) { - // Outer layers are still not done, propagate that information - // back up. - return false; - } - if (level == 0) { - // The core wheel has been fully processed. We can now close - // down the partial tick and pretend that we've just been - // called with a delta containing both the new and original - // amounts. - delta = (ticks_pending_ - 1); - ticks_pending_ = 0; - } else { - return true; - } - } else { - // Zero deltas are only ok when in the middle of a partially - // processed tick. - assert(delta > 0); - } - - while (delta--) { - tick_t now = ++now_[level]; - if (!process_current_slot(now, max_events, level)) { - ticks_pending_ = (delta + 1); - return false; - } - } - return true; -} - -inline bool TimerWheel::process_current_slot(tick_t now, size_t max_events, int level) { - size_t slot_index = now & MASK; - auto slot = &slots_[level][slot_index]; - if (slot_index == 0 && level < MAX_LEVEL) { - if (!advance(1, max_events, level + 1)) { - return false; - } - } - while (slot->events()) { - auto event = slot->pop_event(); - if (level > 0) { - assert((now_[0] & MASK) == 0); - if (now_[0] >= event->scheduled_at()) { - event->execute(); - if (!--max_events) { - return false; - } - } else { - // There's a case to be made that promotion should - // also count as work done. And that would simplify - // this code since the max_events manipulation could - // move to the top of the loop. But it's an order of - // magnitude more expensive to execute a typical - // callback, and promotions will naturally clump while - // events triggering won't. - schedule(event, - event->scheduled_at() - now_[0]); - } - } else { - event->execute(); - if (!--max_events) { - return false; - } - } - } - return true; -} - -inline void TimerWheel::schedule(TimerEventInterface* event, tick_t delta) { - event->set_scheduled_at(now_[0] + delta); - - int level = 0; - while (delta >= NUM_SLOTS) { - delta = (delta + (now_[level] & MASK)) >> WIDTH_BITS; - ++level; - } - - size_t slot_index = (now_[level] + delta) & MASK; - auto slot = &slots_[level][slot_index]; - event->relink(slot); -} - -inline void TimerWheel::schedule_in_range(TimerEventInterface* event, - tick_t start, tick_t end) { - assert(end > start); - if (event->active()) { - auto current = event->scheduled_at() - now_[0]; - // Event is already scheduled to happen in this range. Instead - // of always using the old slot, we could check compute the - // new slot and switch iff it's aligned better than the old one. - // But it seems hard to believe that could be worthwhile. - if (current >= start && current <= end) { - return; - } - } - - // Zero as many bits (in WIDTH_BITS chunks) as possible - // from "end" while still keeping the output in the - // right range. - tick_t mask = ~0; - while ((start & mask) != (end & mask)) { - mask = (mask << WIDTH_BITS); - } - - tick_t delta = end & (mask >> WIDTH_BITS); - - schedule(event, delta); -} - -inline tick_t TimerWheel::ticks_to_next_event(tick_t max, int level) { - if (ticks_pending_) { - return 0; - } - // The actual current time (not the bitshifted time) - tick_t now = now_[0]; - - // Smallest tick (relative to now) we've found. - tick_t min = max; - for (int i = 0; i < NUM_SLOTS; ++i) { - // Note: Unlike the uses of "now", slot index calculations really - // need to use now_. - auto slot_index = (now_[level] + 1 + i) & MASK; - // We've reached slot 0. In normal scheduling this would - // mean advancing the next wheel and promoting or executing - // those events. So we need to look in that slot too - // before proceeding with the rest of this wheel. But we - // can't just accept those results outright, we need to - // check the best result there against the next slot on - // this wheel. - if (slot_index == 0 && level < MAX_LEVEL) { - // Exception: If we're in the core wheel, and slot 0 is - // not empty, there's no point in looking in the outer wheel. - // It's guaranteed that the events actually in slot 0 will be - // executed no later than anything in the outer wheel. - if (level > 0 || !slots_[level][slot_index].events()) { - auto up_slot_index = (now_[level + 1] + 1) & MASK; - const auto& slot = slots_[level + 1][up_slot_index]; - for (auto event = slot.events(); event != NULL; - event = event->next_) { - min = std::min(min, event->scheduled_at() - now); - } - } - } - bool found = false; - const auto& slot = slots_[level][slot_index]; - for (auto event = slot.events(); event != NULL; - event = event->next_) { - min = std::min(min, event->scheduled_at() - now); - // In the core wheel all the events in a slot are guaranteed to - // run at the same time, so it's enough to just look at the first - // one. - if (level == 0) { - return min; - } else { - found = true; - } - } - if (found) { - return min; - } - } - - // Nothing found on this wheel, try the next one (unless the wheel can't - // possibly contain an event scheduled earlier than "max"). - if (level < MAX_LEVEL && - (max >> (WIDTH_BITS * level + 1)) > 0) { - return ticks_to_next_event(max, level + 1); - } - - return max; -} - -#endif // RATAS_TIMER_WHEEL_H - -- 2.16.6