From 50234b1d1363a27a86822a810932584226e86262 Mon Sep 17 00:00:00 2001 From: MasterRoby3 Date: Sun, 27 Aug 2023 16:11:01 +0200 Subject: [PATCH] Finished connection method and fully implemented threads --- testing/connection_method/readme.txt | 2 + .../epoll_data_stats_100.csv | 0 .../epoll_data_stats_1000.csv | 0 .../epoll_data_stats_1000_TIMEOUT.csv | 0 .../epoll_data_stats_1000_TIMEOUT_HARD.csv | 0 .../results/epoll_data_stats_1000_multith.csv | 19 + .../epoll_data_stats_1000_multith_TIMEOUT.csv | 19 + ...l_data_stats_1000_multith_TIMEOUT_HARD.csv | 19 + .../epoll_data_stats_500.csv | 0 ...ct_data_stats_1000desc_NOBLOCK_TIMEOUT.csv | 0 ...ta_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv | 0 testing/threads/ev_build.out | Bin 0 -> 98096 bytes .../threads/event_builder_epoll_multhread.cxx | 351 ++++++++++++++++++ testing/threads/prov.out | Bin 0 -> 17752 bytes testing/threads/provider.cxx | 82 ++++ testing/threads/readme.md | 18 + testing/threads/spawn_clients.sh | 15 + 17 files changed, 525 insertions(+) rename testing/{connection_method => results}/epoll_data_stats_100.csv (100%) rename testing/{connection_method => results}/epoll_data_stats_1000.csv (100%) rename testing/{connection_method => results}/epoll_data_stats_1000_TIMEOUT.csv (100%) rename testing/{connection_method => results}/epoll_data_stats_1000_TIMEOUT_HARD.csv (100%) create mode 100644 testing/results/epoll_data_stats_1000_multith.csv create mode 100644 testing/results/epoll_data_stats_1000_multith_TIMEOUT.csv create mode 100644 testing/results/epoll_data_stats_1000_multith_TIMEOUT_HARD.csv rename testing/{connection_method => results}/epoll_data_stats_500.csv (100%) rename testing/{connection_method => results}/select_data_stats_1000desc_NOBLOCK_TIMEOUT.csv (100%) rename testing/{connection_method => results}/select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv (100%) create mode 100755 testing/threads/ev_build.out create mode 100644 testing/threads/event_builder_epoll_multhread.cxx create mode 100755 testing/threads/prov.out create mode 100644 testing/threads/provider.cxx create mode 100644 testing/threads/readme.md create mode 100755 testing/threads/spawn_clients.sh diff --git a/testing/connection_method/readme.txt b/testing/connection_method/readme.txt index be42d79..0ebc290 100644 --- a/testing/connection_method/readme.txt +++ b/testing/connection_method/readme.txt @@ -15,3 +15,5 @@ The timeout is pretty hard, we're talking 1 second, to hilight the difference in With epoll we see a big rise in throughput with the 2 clients, since we kill cpu time for iteration and optimize the 30 seconds time analysis, in the 50 clients it's not so evident. With 50 we start to see already big improvements with epoll vs select. +Now I try to multithread epoll, to see if the data acquired increases. I'll measure the full bandwith received, I expect a semi-linear increase in performance. +For the multithreading thread check the threads folder \ No newline at end of file diff --git a/testing/connection_method/epoll_data_stats_100.csv b/testing/results/epoll_data_stats_100.csv similarity index 100% rename from testing/connection_method/epoll_data_stats_100.csv rename to testing/results/epoll_data_stats_100.csv diff --git a/testing/connection_method/epoll_data_stats_1000.csv b/testing/results/epoll_data_stats_1000.csv similarity index 100% rename from testing/connection_method/epoll_data_stats_1000.csv rename to testing/results/epoll_data_stats_1000.csv diff --git a/testing/connection_method/epoll_data_stats_1000_TIMEOUT.csv b/testing/results/epoll_data_stats_1000_TIMEOUT.csv similarity index 100% rename from testing/connection_method/epoll_data_stats_1000_TIMEOUT.csv rename to testing/results/epoll_data_stats_1000_TIMEOUT.csv diff --git a/testing/connection_method/epoll_data_stats_1000_TIMEOUT_HARD.csv b/testing/results/epoll_data_stats_1000_TIMEOUT_HARD.csv similarity index 100% rename from testing/connection_method/epoll_data_stats_1000_TIMEOUT_HARD.csv rename to testing/results/epoll_data_stats_1000_TIMEOUT_HARD.csv diff --git a/testing/results/epoll_data_stats_1000_multith.csv b/testing/results/epoll_data_stats_1000_multith.csv new file mode 100644 index 0000000..147718c --- /dev/null +++ b/testing/results/epoll_data_stats_1000_multith.csv @@ -0,0 +1,19 @@ +buffer_size;time;total_received_data; +1;30001.8;121453; +500;30001.8;38315920; +1000;30013.8;60329152; +2000;30005.2;74660074; +3000;30005.9;85193274; +4000;30006.5;96597573; +5000;30008.5;106440822; +10000;30011.8;137147617; +20000;30007.9;176761989; +30000;30006.4;156482849; +40000;30014;177159351; +50000;30049.3;171875036; +100000;30053.9;224264206; +200000;30048.3;225628771; +300000;30121;180069213; +400000;30016.7;156804334; +500000;30000.6;230636978; +1000000;30135;159812471; diff --git a/testing/results/epoll_data_stats_1000_multith_TIMEOUT.csv b/testing/results/epoll_data_stats_1000_multith_TIMEOUT.csv new file mode 100644 index 0000000..cbcb9d5 --- /dev/null +++ b/testing/results/epoll_data_stats_1000_multith_TIMEOUT.csv @@ -0,0 +1,19 @@ +buffer_size;time;total_received_data; +1;30002.1;140629; +500;30003.8;31440572; +1000;30004.1;48545615; +2000;30010.9;65841163; +3000;30011.9;79191486; +4000;30008.6;83061533; +5000;30011.5;82064998; +10000;30005.2;96952555; +20000;30007;132912119; +30000;30005.2;138298731; +40000;30017.7;138156188; +50000;30017.2;139215949; +100000;30051.2;139854062; +200000;30008.9;146022695; +300000;30061.5;142890809; +400000;30083.1;138006324; +500000;30074.4;133424935; +1000000;30000.5;114451148; diff --git a/testing/results/epoll_data_stats_1000_multith_TIMEOUT_HARD.csv b/testing/results/epoll_data_stats_1000_multith_TIMEOUT_HARD.csv new file mode 100644 index 0000000..0b7500d --- /dev/null +++ b/testing/results/epoll_data_stats_1000_multith_TIMEOUT_HARD.csv @@ -0,0 +1,19 @@ +buffer_size;time;total_received_data; +1;30002.1;163986; +500;30019;34088098; +1000;30005.1;50801994; +2000;30006.2;69301651; +3000;30005.4;80399265; +4000;30012.7;90123946; +5000;30010.8;98647263; +10000;30011.7;116325174; +20000;30049.7;134726431; +30000;30025;144562322; +40000;30028.7;147823821; +50000;30012.3;146218628; +100000;30069.2;151376815; +200000;30011.5;138831476; +300000;30022.2;145632228; +400000;30096.8;146447339; +500000;30143.2;134063359; +1000000;30000.4;123787063; diff --git a/testing/connection_method/epoll_data_stats_500.csv b/testing/results/epoll_data_stats_500.csv similarity index 100% rename from testing/connection_method/epoll_data_stats_500.csv rename to testing/results/epoll_data_stats_500.csv diff --git a/testing/connection_method/select_data_stats_1000desc_NOBLOCK_TIMEOUT.csv b/testing/results/select_data_stats_1000desc_NOBLOCK_TIMEOUT.csv similarity index 100% rename from testing/connection_method/select_data_stats_1000desc_NOBLOCK_TIMEOUT.csv rename to testing/results/select_data_stats_1000desc_NOBLOCK_TIMEOUT.csv diff --git a/testing/connection_method/select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv b/testing/results/select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv similarity index 100% rename from testing/connection_method/select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv rename to testing/results/select_data_stats_1000desc_NOBLOCK_TIMEOUT_HARD.csv diff --git a/testing/threads/ev_build.out b/testing/threads/ev_build.out new file mode 100755 index 0000000000000000000000000000000000000000..7c9cac044ee7d9e51c9c86b3f2f14aacdf83c2e9 GIT binary patch literal 98096 zcmeFa4_s7L`agaFH7rvyD@t3(G8at^5Dhg8m9at52+*js5n+%qm?0PtOUn&)nUHeZ z{;;i|mTmh(yX|IWMP`P7HdxnBQMoN!R@9meX+`GlvaQAU{hafhxpyveN4Nd$>-Bqm zzg}PXzUTcs=Q-y*=Q;oGT$nrTnRB9}qBM2IXjf{KYPnc4X)H)wsq3U^soEJ@nr72R zY6BqehaaV9#^PuQaVdUN6%Mjrl}*YgylfwO2`Ap)nu%CiZ`&Jof!i3~(bHr%7JrBX>}~M$XsB`4q;n zzZ5Eek~#X>!*VmGLq?ZE(xofw6JH_Sm(+-4A6$2agojxHRo*&-^~6? z>8!ceO&&DtjU_{?es|V=RBx&S*&`jgNS})n_p^~Exop=@qBCHbI6Hpk;HTa7dTGT2 zr$v97xAcF`X&6Kz%WD;aZD<&2hXubLl?kW+3sfi^|0@eS^I_+#Fy(%2q5p}6{mmBo z7hC9)N5j=~lZBlJE%<%tkZ^VeTli;-g&muP{x%E!FD=^DV9~B47Ir93!qtB=f+`%J zkH8Ga+br~-v?%vO3x1MCyJ&g|SMIkKew%Dj&j&5+ziiQu9Txg;TGapd7W}6c{Am{a zC#X-jaWT}w&&w?8A7i1v*TQc(7Jh59;D2txPq*OrS+w^|i+WDC;QwJ^Kh>gL<1GAB zXrceQMZeRWY{QTFT4B+yY76^47WxY<+B@5VM>WINXOBhw$6M&%Wl^7BS@>-X>T{9V z2}oZL{j;>;n(ePr7*7?%^#XoIY3FK7d4G@~SWVl3ek6VEV@brZzUFi;FZFty6~6p( zpVO&1GjiuU3ti=|=LiXm7Bk;#3f~6C1t+ia#wz#vjG45pm@WAc{#qz zoz8;l>ZGKk6FQv|c5^urHlRVy)cB;^V9B)a5y)by^7I);;^dy4<*~{^z zxIBd=;i_-9uK5&1201q=g&S7HEeqoX`)pZej&D+d+avQ?G&xLe84EChe$JkkGl>gM zb$ctEDBG2i;c@#yT9q{?JI9;jlpU3Xl4Q&*LpJgi8{l3GtY}%w3g4kyYV_ z6Z0!7oW50ME~nd5#O+(< ztV*PE5LOYxGG&F=?cpw={$XF8tZP%eWiAi7hGNW_0iRq0qSRaHk~KZ4{+W#6sc?x( zSjZBa)IgkU%4_{vXiOk-X&jp>sd(hEH+-6$~IRZ&@r z?xNYu<8>lH^L=iwM-!c*&D$QW40ElohyxnaRyEX0U8NPUw+yw=a6{(3C`%eD z@Rex!KCfFP#Y~>0Rg}0~Wo)Jh6JUw^R+m;(;DI*Gm3phFB{+l8^iC^CX+DNL>Q_uP zSytgIEV%SiI*m=C!CQ@iPcNQae_p&qP|&1_xPr zil=g@OtL4hD4a}JV2_~oOIc%9;bcBoyB8c?QLuI+%QqpN-}4}L4rgi)F;^zigS00( zz3R=Uk^gk9nbU7SeKU3}vD)uBeT&dPO>5_LxkwMtKIF7pr2A`MaN0NaUObBEr+tew zT~VliEz8o7KHu#=Q-dc4;&}(Pq5ORJKn-3wo70sSP&!5%$Y9{C2j#)% zDI~)0j^)@kPvUGVxlCwA1;K zMD_eerB(T~ZTlg9$X9eVupQ#r#e(1Rp#Z_nmbc>nW&?k=fp0PJ=NkAn1D|T(+YS5- z1K(lbuQc$T20qQe2MqiyBhP-Ic5zn;soK{fD8=)aU>4rj5(x?>UMDZt0W>;?I+};{WDOnIJx1 z-irTQI%R_R^X0AhzpYayi04Pef@nAJI6Vcg4g;^AMU$}8z+XrNUx7|}L-v2b96@)d zOb|a(-irTwI%R@*o4l3(^SB^>l!1>m@D~~QI0JvNfsZ%vJmm?g&A?w`&`&V%V+?$v zfmdfu5~mvYu?GD#13%8dI}H4#20qKc)0tXbc?N!hB7sW{{6qs^Y~U|5@MQ)*(ZE+5 z_#^|r*1#tl_*w%$$-r+i@L~(WvIYY`#h~A4;4e4uO$L6df!|`_ry2NW13%rsw;1>< z41Ak`zskV38~B+9{?zR$51jJADG!|T!2g{daMT=$b=39$-&ZxwvA)F@-P`V{*%P}v z*x265A4Al8$wB--WMmrdC|ykQuFhUum%K~qC`z}B^jnmsEp=CmNbjXIZKb=mi1aQ> z(-yj`QKYv~nzrp-n?(9qO4AXiYpqECn$oll>M9fIM<`8O=dPt9{Sc*T%iNVE()UuD zw#r>;B7GO7X^Y&IDAIRQnzqJWHj%!S(zGS+iWBK_O4C-jOB3l8lpaFq?(aZcvW(KS z_3i2u=^H3bTi&jAk+9cA+l%}Iu z*IJPtM`_yfc9n_rMU7kUSt!-DDNS{t=+R}C1)X;+I# z@1-t}Kzhm(sN5>`D{qyC_Xt&8|d|zLV0l#q6?)^sSVptz}o7NS9NZwv=6(NUxwY zZ6&+9kBk1NG;JZfIz{>hO4HV{t6ikCDNS3(t`?D=OKI9Fc5M;qS(K)uZdap7Pop$# z8M`)#bTXxBtJt+xq{mU3wuoJ2BK^(FnpU(4X>lcep5cGXe*5t{`|+KDk?UG~=c2Y(-Uz`9@YJiM7g&rwg!~V?*@n%(=7_&CP}FMgj@DZ3 z$DpIt*#kpfZ1J}SoUm8qw;y%X&+o3YAK6Bu+~I#6l7*1yWdv@3h15_X4+RTJ6NMbvL6ft;RaQ9@ zQokK-39Q{0>)(a!^oe3nJOSb%FWTRd{<;dz9r9vFoqa#rvkL_}{I8K0cKY9iA4Uc1 z{pWvDYmPYTmh?z(1Z(fF+|p{_#|_vQ(tu>yfSNT&dMlFx>&S#w({sjKcu~=BQgwhRGYx$KmEB zRJnH>hw`VWm*3u8v!=PXlE&bUJmgJAqh&C6;I7pUd(zyS(VKuojoV zVuxcwi?CSJ8N0rvGCQmy7p)ZIpg1Zxt?k>pIn|hyG3hzZLbn0v*-$ z2Kn3H>G1EaTQ7Q~!BG>4a`^2{4*xDk&90~n|Nfbn4oQpC@5~e(?WoU+Y8JzTGDNk% zME4@F9sl^sadS(YW9%NXT+@QA_QqEGX0pPiz`=Euji|>Z#8uEE@^xC!d3EdzCg- zf#3WC!%0Y^eF^Aep@1+G9<9S#CdbKre^b$P7cwZlnigzcq1zf5Ekf{Mo&BK5=niJQ z5gA+UwPG>Yic0$J8|&;F9rX)qXExK!=J3C{jTRF%yl;ddea5^Tb^^t4n~dbaC>y!! z79R9d@HN36lDIn`-Hf}wQ_gV|@3(i>**keY-54^Tz7MgZetoyCyLX#5d60&+o~qOu z*eV6>Pm|YL18!_+<;edH_2K$`;OoTyn2N-h`#IM80M$>{v`|FgM!$V+>-yCgs$x=G zxKZYD)YlWInp_Rt;EYD&w~B0)qXyDeJmje47OqPY>Vo7ZPFBfe87E&xQnsRg#)mJ$ zPCtZftNqB=s6p%c+~0mqRY8Q(-HfzZL$o3HtU*68Vf*E2+K_dAXv`3|_iUis#tl)L z&m-WD>KR$PHO+UOfIC*qh{M*>oZ0H&pE5Slm!mHr3rvRi=f3rpLlu6`9{0mEIBY z-5U5BN0HX`BcO_!qgixU(-Sk~9@=WiB+Y#F>(d}`_}`)4oq&sqVj{fm^NMdo-BIl6h;;2bX)wC3XeM{7iURhH?-Kg*WJ zpGTW8ku5?q-zBPk#=z$gmHTC{iJFKGJ$ozID}`NIKf%8LEZADoMZ4?zZ`eXcMbmeK zJiG~3ACgv|BhA~TrVM7O_a2!PnKSgv8=x2XsGB6~Q_&S_!2FIX@iq>pul@kR5cu#b zn!5rN7&U7GF?Xb6Th=Fdx}n}GKHCaP4Sm)FDfu!T)u^!tq7K9VGp?p$_K4nGpNQfE zi)2+2M6ldXHG(5WN(Shb)5r=Y{(74HTLT+px*6$aO4BRkMMJ)9IqDcPuI1>Ev)0>S z;^>gLddB{1;H0BNuHUI-j{5sagi_?ZA>!*{s!_cdW)R5fMhK!PF6-~7szM+q9w8`% zAUH0g+Wlfyfr+c~I|k!`39q8^k$3^oek6<6IAs_j7Lq%4lH83A}utpa-hIkM< z9|ndars2NB*HFb<1DU}LvO2ASi86y2W*-KQd@j^?u=<6v4}^P>Tlh*Z>mF*LYFKNa z5y`Gc#1s_l-_0-}7eQqI1uDP3Wyt-s(;1F&;Y2BNyKxDMm5bkSWT0a!8CF5EQr1Fs z!UuR71*vlLKWT8N_-zdglgW1OvC9y2{*Er%4GTxf$#MM`m`yI1gqZt$L=2U#RMFfb ze8IC*Yv36q564Iq71GbpvUZ;2RBiu2rdUr^`O?rT&k3z^KI*7)sCuu&BRYq_gZeC< znjbvN@oB|h*;BLTcvNNbkJexZg%kf+IP}odm}uN6-%)=~`ESWBlivn~nY83LWUe(Z z0*&A!@(#)-o&G3xCvpRcGj5N=U)k-bvv(VqI(rX-YRT?R;#hCcaUecP=#SeZ)p3wQ z)#?`F=-o4_-I#;aTB&C>R;8AR@`QobKp8}cjQ)Wi9}ZSBs3Yryf?5L(rRRj6qi!Kp z76LIt!IQMJ=5udo?hwT|^ql^zz=nDRFuMx-bKwnP5)T<@Skz4m(DTxo?kIk?5N!WK zc*WlBn7Rw6Q}&jrO><;1(r+eNbOhNx)B)8Co3AZGzI72~k!;SziegpXfC#ckHupuy zR~tbV$tImYRXyn#E?pWxHw0cr)3pr$9>@Cks)uI!KMib$4>Ry|-BEKm>TnmfVte9n zT$24nIpamA(<+WfaU;ouqdw0jaO!S6YN$CJOEc)TD3Y>=j6h@Dj>2dTK6R3jD=~iMcXyZ4@R5E;M8&*e2{qn|pB| zv}77V2drduS#hW-YKtChcZ_Wlk5B#BQc8}%|2p-?$uLCm)20i8jKZPyL2lj59vuRbs0b6VY{H=i*;+YPHG$~50TiX07;d`={>m9RHb@&S?j zJ(95B8lbw;!iC4*lw5(NXdxzed|aF}-~Z3~{_aeFS0+Aog8WXBV=+S~wb8?J$a0DM3=fj}dgAaCO zEFDv^^p$uH*Nv*tJc*bN?RU9e{SQ5KqmZn}!cdPTQif9l(dg=6rZ|+|CjdKc0;fe#~B~g4@EFSCf^q3WU_#(l=j{%&%9R8gm)=5$3>p{LgV=x%= zCs%eAKL0k9-A|TiEIT%A+4myfe_D1No$4dDJ2!0E| z&Y;ccd^P%?Hbyg-7u;)76zDcW50H<_jN$fgTf*4n6YYPc4fDd3cT#Ogvu;CX7@Pmi zHhhXVea!uSQf)XOGluJjKp30<%{J78Det7(P;F>~ia2^+P(N&aFxZ1fpiqV1_f=3M zO0Go+^wz*)Xc10EL0HBR)6sBth|dh#V@V6zm-W>S9U&*3GVhw&#F5p%uo=6iE!Z_R zVb|1%vC%@s{*;d6VwVGPYv5jyq&?6UO4f)Z?U2Nl=uVNO{Zk`Je}p7<3JqebRU{I- zUrj~p19k6`q*ZK`GVA6y%=hUgH6f*HMv5<8tE;vJl&Q5DO#1qu}T7tc73u@AQ$j=ydih^;3!hA@R zwA|Tj18WG6fd0rqJcs5vmReX0qv(c8_$nQ;2i+#K;BkSZ=`BFeEudR~)Ed!SUyILF=s<`r z8Kg!A-ebVljiNQye~71@4dI+knF__PlufG|b?7>J1c^71yZ13jqVi%BE~@(kmFlPJQh%dhQQcqYb?Jmi(e&0&;QBvPj@^Ns0#W5~Q{Mg?s(MW?L@&3UHCX%15Qpp=HO zJ}M@KW_t%m`M#s#FlP%X@SpTbgg%}&i=5^HpW&S0Mn$tQU>+4)i0wNnq79=WLsw}D zKPn8ar``x16@%VJ2_d7Rueul&SEKU!s2CWmu5naE>2>KejEcu`UJlIOFFX|ZjX*If zI_dU=qv9ByRr`#JBl0Awwi5s5TJiBD!>IU36mY^((f$=RpwC)yv+Pv!sJKtkEpRxx zMIRMoRBOKXT9GXtN(4v6eDN}#dFpm>sD(`3@u4}-7CFs9I+%0nqv9hm9Rv$JK&SIQ zYsJ8D1wIj)^AVBLT;Lnh{ef_!qDUApkBXa!?K>)rYsEk4Eeok)F)DtKWdT(|??m+- z6@PyN*+WJ}Uv)7mT&TQ0Dqf^gMW`A_#nXCSIt`;D7j$64o0MaB;C_K(RP3c&eN-5? z-Nw%{^-o9C4*L5@`<%)7+|Xx-tq!~L!5Y>kJoFSBIzH9v>s2*Ac`>Y4!G$h#qqt6L z1zU0Q_U}9?`*(kD`-LZEzwCS4pL0_7v%_c!AGZd`0B^5DyGb3uSZ}=03wjt^x)wZjf4Y!GQkNv#)gpfGE37>t2|;At#Q49C8b@PVXe7MvM}(2Eo` zyWljugwopkmMScmQMJPs9Pna#z{-bCcoWsb>tA@~>nyR(qS~*$iruajNcccV?41y) zcG3wi6=pgx%d}&bLF~!1?2}@HOrI=6)Ed}M$+5c~{&&H&(_0Sr(wjT@WfIx-WqaXr z*4-4E^+zI!x`_9rfYOciMAvEblDJ&6MLD^|PPGThhbn6}W~v4&W-yq;wEqm~b9dNB zsPsDyhSmuSS)ue>Syi~2!4NyP8wgmil>l`3D)3U+a52l(gH znu8y4AmnpJYk=NKk~!1^1N0N#3Gn08<)7cKYS)k2DLyn3-S{`LrAP4NTDI5g`$BH1TK+<1kjZ;UJ><&YSe$c!E%Bfy+gj4Z(iorV}$Ad-5F zL>v5op>l#4IZQ8aeV-UPfQ%;*BcGB#^cd+7$uKc;kOU_aBcDUD&-6m`zGcMF^b+(J zPb_cz1>8x-OkJ=EV!S_0$p|qM|C$~%<)K*%M6yrJ&|gdK8#7Z#IV5JHnbBjWyZ=eX zj9r|)g7eB0ky z_l41G>$6_=t?PCFv4wNOS`eq_;0hj^3cEXOM&-9)k!T8i>tIQ<*d2NTw2`8{(I#5j zN=1@(P7RdI5=q)uHBxetNbW%r#;_YiGW0zH@eq2H7&vt3&P#wQ%5DuD{**>G?cr#d z7ix`Aqxa_=re8M-nH{-5@0BLe53PZHVwBJ>Do*dyIO87a4rm9L*8f=2PGzIq^}1Dd zza#k8K&<{onBg#{LKC|%`h*61l&QNa2GG4&QPd}^#?^oyuFKyJlaDQL(#thRp2bGN zW6pv74Ym^cr{B*|li=E*lR^VpnC){$d`!36cSMAE`3o`+k3AZigZeUz$D)HDdr2e0 zYw|M&qZ^*kjh&<$UNq-0yWtzE=fCR)YMgpk;RJq|!n4p3y&@+OIVT8*FLh%l>4#o( z4znL-Q9b`%KTzZP`XO{a5-HUl>V5>pb#Db{R`qMIHAfOdP7eP0E%=YkPGZK{3P(WRfr-fmY$v^?(Blbd z6k0?RQX)@C>iq!jW#qsZrlE{>1kd8Z*@~MtfQ$skm5gW>t;ZfYyrf6(Ar27Jm|zQ^ z>3Xv71CC~Fqv#rf*%iY}9^K@WMIQ=dn$(B=+oJs;y#~XLltF9b6 z(&*52qI!KCdMDlv$F$Bxn!AqdAyjY<^wVT2!#|fS8T^^}a?qc6?Y1=#2meZYC-CP; z7&7=XPSlW&P-t6gAW9@n{``ijdqRI+PFcUFKL;XjumeK<84{p_MfLjlGg&^}{&)QO z0kz5C&(4>E{uJ@qvh5`O`6LV({P_^s)#I~HBu)OL--|f0KX;PW_w?sak(Z-E{DA=T zGZvmHd6sOZp8p>_oXPM9r^U@88JrgHKvKQ*DdxnRMD4_!7%xX3exD0UJSWocBGH_f zD&|BrBdRG~Zg3Fa_uY}v@~(K5_H=9aCO2cwXd zZG`u@;Vee{eD9Xgw@`#{*3WMO=lWP3)aD5!_v&eRad)gx^yOtWDPp7wtB)w{b#?sSBhyRVh?L>xolFFrA zfM1z9K`D=imhxb@QXY+5%H1a}WnXA1uY@awoM>oE7{7>~7hQe0BiNDOiEN^uV^u%D ztBdK=-%ZkN$ktj-eCXqcp)Kb>aXgl@Fh-C5S)H6g#jX(Na#8u#0R2q`>rmx~yl;J@ zLR9qWZX^wTx)n*eaids!Mi{2QGk`XV$H>BMDn>)9&vlWGYz@42GIgToySCQ@w0_)T>Gp=|G-orgC(el876eS z`To{l`>$HRKazDduNi!};7=jriR1P}9-?<>*+b?-y7*8ht{LLyuM8cnh&>4aOvj5Y!j@_>-(#q`QM|} zm`_7$KR`FnVy=DYc&I<;%oUUu%@iLa16l*0{Z>4L2-W0uW(Q8wq%L3Mg>wDxXyNIr zOMkcsVjN}k^-@I;+cL_GpMcZoZbKn$WZ)5M8!#I~T0V*ubRE;@3z{B#2-?SVCs6M5 z1-*pnCj=eb@6Tb{Ban`VLi;kNCj&#D;9@0)dqC5EBHsLH);v?lwS*gcBTZz;T?z~a ze~3mtYgAZjEN6{tEj661L0gFMrMOsQrKQHrtT7>|VeFh#(K+;c(tTe#Z=?p&?>fnj zYNF&+e3T`hOKqX#6d|PpSTiMi+toq^d#!>jtEZTA&$TEB=vl{o+*+Il88Z2q+5unmuICHlIvuVv+AJmezK6u3oSK#dawPsPSh$+kwAe^W^H7*})wE#h zYYjYTB}LTYS68j1u_Rp?UJA+0x`d-h>_X(sZDhnM9ujD#;qyIYMH7dNT!#u^;Lf}* zvwnuRK+|R}%J9E4b76-6Z!>de`j0Pk)K4e|os&8CTa4t`!0g8nlRLkS@eNOUZ^%e3 z(|;6EmG1v^X78{M9W}e798=$~{0#GO?2Sv*pX9^eRMmE)5Xw&yx<7TD^1vw%obtda z5B$IBfhfbbU*QQ6UGnP)ZAJO+5?7)47D07CC*5{Qp>3JB(o<;jd2MChavzA(@uhy^ zy9g<>RFMR}1(wu2u9da|ugBvmpzlAdI9+}BA*pM#g92Moxwq6-?5%*!it)<$c$=_z zy8608U&%CK%t^IG{+Z%?6kUZj@$H7T3g4;{m!ULi^pc8csJF0RR5(pkIahtpYvFhs zzJ$@`u7Zu6jH?&S%!Hgv6JNSG8(*SHEdjf*B7eCH`71>27F3olbCugp*YK^ha0I(8 z=oG^@FQT4vgg40@^1E}nzD4k{tLg3kPuHev_>V4wALz?TE!=?bFDx(5Uo~x7zHge%>GaqVRu;Ppif!%+ z+a^g}~>4>wvcBdwZLJNx&Z9I$%7$jpK1( zD)4n+9`G|@H8AxB_!+nw*aCbM*a>U_YD4jjn)noFG%%Y!%>mvDq;KmRu7y$kZ7<;a!?FS|R=?~^OfWuxzeqai)7B~mk1k3}r0o}j=uo@V9o~GRg zOaSfzI)JYO>03+swIDxmD6k251+Wd62Mho=0Au4d?OtF4unp({z5^8BaUDz^EK@uU;=Ot&;jfO(zl`v-i7?Y3xG|)EMOb(CSU+q3yi%$)1Cw- z0QUkNz#brdi^`bY$PY{bHUVb=+kjcX0PrSY>~N&J7?SZ{9{Fb%jASOHuMd<@tK>;dip{@~BOy$6Bgf&DH<{eYu^DIMr9 zpbuCKd;(Yt{0p!NIQ}n~M}gVEBfxdQL8CQoJ8(Sk3t%SjJ75Vg@m4fepY3z-FKW*a7?ksEx(^)!Ex?1O5=04x9-r z1l|Z-2Xq4;1=axf0AB+h1nvj+8>eaKeuRDl-U@U8e+4WC?g!SA{A2VRa5S(DSOg3J z_W}o9s%c*X#{)UBcfKLH0IEZlyoDJ+IIWTTK{Q3#n4IBr|16~WP z2Hp&80ImWy1Ahwa0PX;j{AHLwfL8!t2QCJF23!r) zy0D%CF92=_76ChfYk^v#rtJfc1|9;Y1Cu|4-+{HjjleCyr+_a5_W|Dr9syo`7=BAa zzXB71Zv%6Ie*^k}OOK%5!25vBz#YI2;2Xdm;QPS%WXz-Z`@*R}`a8pUzzM)=;B;UE zuo&13ycO61tOND{e+G=7gg64G0y}_tz+PZAaQqj@54;}O4BP=R3F2}qEOav|fW&sxi z%YZ9@n}8P`Lq7wr03HA?0v-pJ0Y{{2+FigafR6$f19t#d13Q45f%Gi^+ktU^Lw?{y z;BjCkaKu!U1H1xQ3tS9*1h^VV--odo_3hz>k2(fnNegOv8EvyaIT}-;p0U z8n_v_4tNka3?WNb)UDZCRCQd`@Ij}=Zi+fBj(9Aq+LrrzdogT-S9pEcg$C(&Zh~K8 za5Fe=&fxgDL(W(kyH>mEg6ZQXjmD}W%S#73U^kWsz9{cv{ET?4w|6LUGY7|Qh@O4s zfcdBp@%UMdpTUry1q{kFb@^uEA;)sA%ky;kcF^BGiuKYczeblI0DlznbB*$Ab@_4d z0m!MX!SbEDd_e`d$tPuG;A-91$4*7kM?=Z^kH8Ig! zWf`Pni$)CJ-`o2G=my&eotR-!LMa|}I&=~q;J8x#3|_Pg7r3U)8-M*G z$nmXc7`)c`>CcoO|CO~o5%Qi0@+`=YMUa<4-W@@{3GyQmbelUW(8}iNw za(Y+#Km>Urf;NH zHWuoAOuwrT4Y}PYk4_T`HgNkP{~_chMmfdxGTjFKT0t3f!p%Jtm)j91BN3N>9f){J z#YRcRr3115Sj@z@=#>+3xb06Csm_l6IHSW}wz14;IoXk%z5%ol@{5e}C3<~oAuoa) zTS>hvLw%bd_dp&l?rq3Yf__~A`Fz~>Ys1D+)i>G^^b5t-eb7lKohE~hVNQt~fVC(> zJrW_`9-$t`P)4(=hr>{Yp&s$@{l}^v2?iZQJsMC>H0DMte>6i*bFY;@R-=pokV}7H zqaDT{^jmg`(2@Qy=oso@I}I@%p&n_F=S8STKlEF!s)xf+hQS{R(79dJBf+3!s7DjZ zc^EqL(06)U=7_$f_-ccEFXWdP!V)9c#+dmlhQ!B}2_E^mhX5aigJ>9%MBL6ZE@ zftzn3$JSAo%PC06>8}nCeZqR}j30>c7D1j0`Q8ZfJjlm1h4%;5uNw045#$Y!Cr6Ms zL!JuxSY!JN4ef_~CgjtNa?F9ZK!wWhfqZd<{PCx2nkz#7RLIvx$e#zfKSF-`t2&QD zZZp>JM!o(GCy+OvK;FUfaPzxpKjaUfd@FhU8Q7yokf%bv3i83m`e*3%&x5=e@^JH$ z=zquyA;%F^k59LrzX9@c$N{=s4tEj1%@EuKxmA33K<^ILr&wzO5OlD`G2A@zhQhdLr&wM_r{9-XjL{yXb>XjlO1Ah)WA4f0zdx2nfM)T0P;QIEs;;K0Hk#k9~oWBn|n7V_`5 zSj(FrKORBe2KhITTg7Vt@<0T6EFRLl6G5H;IlU7f&JVPnIUs);@`<<)`oJ(=iy?mn z@-ara;aN%T3G6qWz<%2a><3O@Klbd%^-q92QvDr}NAgec3GCONzhc|!gz4|5I>EOZ^eDTOVQ&h&W-cgBT_#BI(e`+8u9+7 z(VkKFRejD`2i?8UwTg{LA#aZ$-vjwOkX!lYAm_J|_d7?HZ{@qukT=8rrN*`t>Ge;C zd^hA)`3oU`7VvpC4AxAH>|xSIzZtNy+M z@|!HmpgJywybSVG+z00i3I-%ez8dn{2>CZd{t)C=Yx8!6wLH`)%$lvL{qIWyKgKoI~6yqQAxEHMF zKzbMC^a%1;Opg5`$P*x^@~xg%mxk;~oG2}6jTg{=hkPn93YG2y~c|7En z?T36EYAilvEQK6y(#Ilyu0-da1jxyMj~V6j?vAPN zx3PcCfav=vl2C+}1-(Pi1L$`6GfNw&VJP4rm(%alp}LOYGpzfN`90_$WOcdm^AE`X z6hXcp@;4y2YU?q`Ux|=^7>+S7LO#n_{u+I(q(J^|1pB#=w^`)3!KM%L&mb=_+83V@ zMT<{A$&U@t8HaZft)6c-Lp}*|t9a;uJRNeYHuOMV1i6)u;&G(Rwa8CxNQJx#@ZzJTd zh5Rt&R`qX!ya#ft`nN%T6mqNj2OvKbq5Rm3@oWontNJHEe%?#g@#BEJKjh)+Z$qCH zLp~JpTa5i9=REP$o%(nqbe2MAtWn4Cna)#?uYf$<8b$f(eN6hxN;u-^F=%+-h2GO# z40$*o+K^=s2J9lp=Na?U8BiWo#rl>Ao!cYW$b!831U7uoX^ddwKFA-6V1w$~44qxj zS!AxO;r*cl&^ZPjt2yI1+eC>ez4alwL*J8+Dfjr#!pz>=W-wQc*M7pmH?}{}+zCA+uZIJ&qLiqv6 ze;%RySOiH^gz^(0e<(uv^pSR5gz}3ar#`Z5Kja%Cl-~q-HRJ%@KgRVBf;%GE4?w;# zf;<)n(w{|;(`yNjL+&(|&mT-s|Iw=rpG1%sLq7Ut>-@El7ea0oe@&2kAh%k7+aS+g zZT)^i0P-7OhVo@;3!_BS8s?lpI^gAoNjromd^=I_8HW#{|L)U67_#l4| z@^JGC`SL!<-;W^Q3i*c-Cl9PmYjZLqLs>Ah$t2CW8Gm$cIJ9zZCMp z5%RBv{5X6WZcQftG(!G&$gTX-0{KA;IrUX1v1~>5BhJ4(3bI#=S7fb zLY^H#UIKY$1o=kD=R}Y{1$kNo`98>}MUWqXJSBpB5GLn|kmG2m&k@(_{uvKB#fp_Y z6Y_BpOeALI{K_4eYU4!!@fWdEguIs*AxcMF%2B*#(oH%oE!mPozS%c%D zKMP-qgO8K7l*{mZ0(PRv4qr%}<&UDbn4js_e?xz5WB>m6Ws2UYD>CUV?4!}www$dU z>fitFv$eegN)8RxnqvF^a;WxhZ2xD6YU>An9J70PI=&z2Tpn5lm||E;FJgc%N}UN zXB~9?I7Q-8PRkU|g73?_xC)8W7>gK{-hYfWp%&D^^Tq*^SLqd|bhRm6%jrSNoK4=G z$?0RO}h23@fdw7-4V>lNu3NyyVQ-lZNW(_9TL zjpe6vzDrM&H)n7fubPQVJe%Nq0?vj9b&|vb1aYNtLE`gFFlix`U-s~9&hKEU`mqqK@)^O3rfc=hbr(`*Upu4V3gk1Z*2V)DeK2~)=M zoh>;rIVmwIDKRvUITeG)VNKCymd0wdwkIqfgRgWBr{7PDjS0v156%}xX^b`?IIo2A zr)g^Zh4QhQ8n>bRKuygDq5SEZnm0mu%u+TZBkyChL7FWrf2Ov@)DM&+MjNcPgyn~5 zYCe{h<^M4>3$HaYia$#$sR_pq)w=Hv$Dgeg?+C{a)6~3gl*VZ11n2uu{#?x#X1<8Q ztQ&3~iNUP8wG^|P=htpT9kuHnEZ9na+UY(J5v<^nY z|J^444`$wGTJJ|OZ{7!74n7L?Nj-=gaW8SUxbN$?72v5{wZD+scsEYy_x1n%;KSAb zMWG+3#jeE-E@~%TZ{a5jaWZf%rF8yNaUZ9hzLr>>KPK*nYYtQWV_=Z%3|dRtR0nyD zV?J)JOsjIQVE!xU)xJxu|DePAVT-UoR4WV<&*A*G zgAC!9*v#YQ%WEe~asB@2P&%P{8iG98W$esUn!RS1roHknK#crhrx%7lPENV z?04QM4XF8KJoD|Q_GU4^f&D*^%e{m7O+4<@7L)#tLmW<--5;?c!!N*xtIxA+=Uk^$ zRPBl$B* zGnoGek1rKJF6NK&{IAB*D&{lo(*8sV+EdKG;+Dh&=3@}pRBqOENvQgd03Xh8m$7~e zm#gN(8|G=64RK=LA9`5-S)PB?{P3iO{cWs&?owGFHGb(AW6m<{xBGGZ2V)CP^>0`x z2{jMU@9z`;PmU9ItM)$g<2i7YpT7VfuDxfY!enPkk+eUS%S~q9#^YMGYZ3EX;Saj# z_v-0-7W^pf+~9L6^*m!F3MKmoO#OZx^ED2cAI%rn9n6K705PcN5zk_7E3=F1mKLiPLk7zkwNz8R9Izt=>Uhk1?Lb*ZGa zM&|dINdj&Z*G}diNt0<6haWJ%*|aX4d7doy@KULtEJ3?b@SHF}73+6$yXsi>I(StF zgSvK*_0tL^%fm?N*?E%r({GaYTO?@1k&)^@hWjyt`AN*1_oXiI;ry_g z^|!MFRJnekKUlkw7b5yQd34=vVdqb5=RuygRs4^KK@o3k|A*3yb_4U~ecE#7_i}rc z|FXQ!)HuD8`3@czsJ6K7V&1$j{WbGbs-&LM zzX%gM**EVSF9#pa&-tuBewws1UxM}{=Ho7x1eznRhb-*;mi5j1()Ylh6@5XU=Vbxb zZ=56TDnCs6fvo>v_D^trX8st*?I^C#oy@OYB#AcWf5ZG!OC+KC>pkXwwoLM>UG#f- zLjtA}r z?Kj{@(fVE^4Y=7(JSHO2Z_Jg%o6P@``4XojE@plQ^TSMj_=x$rtdFF)qLGp8o97=N z^V)2wr`E4$m|w^BXE$l>;KTLf`J<)%rg_qi@-scRqH_0`?EjQ`^Ew`djv)Pw*GfAG zdvRUGd;*VO6%TdHo7b1WGM|2n%&+3%bOhumjIY2)l8=?3jR8;PR?n2gSmtLkZ+^bv zW&XtK&*Z>o z_i1)Goa~Qd9@{E$RWg6ka+y~8zhb_Z>v<{bzr_4X(|G(V^H-U8`dj?r;&}>qs?QHS z(y$swHOzm<@jRK!eU|xTjyGlVZRXQBKy0jkCMrz!&Eso4^X7Awo%yT0q4l|!`3v(U zkFXclpP6^@epSWK)#GKkSv-zZKfcQRBNa0LZnl$$4FJ`1$23W(c-X-Fu5`&OKRnO8 z!!&Q~XZ|R!*Q!486Q%uWCV%EIZ;sDfnK!SqKV|+%iLB2&uKzCPAG%T!2tRQRxlER8 zey)|wd<)lK`KOKf53iT`liAKcm^bgw3lqb~)k^T>&;Q~5Cl7DUmL&N^o(Ilg`{~Rt znktF;%zK#sC6BM^%+q%eko|_mlE5?~uEWgxSIG2W=6`^Okp8c)m4upa7c;-q6t@q6 zAIf=+@HFdBnIl=aU0n2C24vs7zML~Dyq#L`q(8zV^D95RZlOOZMe09%v(&#uf_5kK z=6URo%x_&L6(3{$u?S#MPqw4xnFpC4V3&#*&f;oje)>|GhI_>ogY}r~jNt{7hle(T z`M7MUr`qLEJjX4jDRKRn`E6A)t@^8t`F&o=!!6?af_Za4(t1PnF|WT)=FR)_Cg%Ud z{^xMfZkk8^rGIXCDVO^;>#O%r6h9O3P33Ojd0Vw>Df8xdzKi)p-nXc6N8imrcFdnU zbb${ShZ8VP!tqyuCp$^2WW|*~tAzew?PZ?W8l$EB9t%4(Uyz;bQmF^Gi0f_U&HK+Y zFmKX+Qhi>j=AUZtWamB}xN2T~ocXyNpDM1t0#E+$!oG>F+azcMke}>me6Cl1p2NKP zxnd6ZaQ-P{{Y$u9wT?W`{6X%QWG*)b@lECS=K+W5U0jzje~9-Xsy+*tpU4}Q+gSe= z<}*z3wwZbJ{`OVy;p*SP`sU|j7tN6M{3#FU3%J}m=2t9{glgBz%s2A5Q~Hyzeo%Wq z;r)i<^O?_J|0_S#GjDzlKfcvjOe4W8=1-84?00DqR@J&?F4Y3LQ!U%gbOFJk*2Fkh4>2~02I z8V*OPIxr>R8t|fDct4=}>o(>m!ryeMxO#&5BRP`aDnUEzYH4Q-_hSL`cQ8NLG{60W z`R6=RQPn@)A?=v=OOG%g%l$H%?LWu-G_Jqu#~$XR*a4TY{-})b{+|k-{Lo-pUtG-3 zg+02k?279#<_qBux+Y4{-e&#}`H~pNeAHZN{}|72%FpAN_nPXtkokL@(twKFo0)%y z{n^a+{{%if}< zVGJAUhXs!O^Mq+VO=RB3{iw$EQs#%aq=6*1^Dy&=u9bwU&jIFtZ;Gqf1+rZ8xnlwI zZK=_O7h!?}aDSjUFjVAjWn17u6@o)?C=J$CvFmL`m@p0zk zO!M0z@HBqS`@o}0pW}QiJ1J>lc)t~ZC%>83o&RP29(IfxFJD{OId4&T`w8I5{y3fo z&f@xHFz;l)B{BbF=FOikzskIMooZ*^{N6$g#Z^b%K z*BKJT=LE!?-%BZB{kvC6MdhClm^VMin1Fo)*}1Ax>OaBuf608ODSqByeshXcR5AZ& z=FRV2L|rfK$FGq3D$Xxte(wUwtMy_P^XAXl_kdSraTNu0Snyx7o$-^UHjX*s8h~|< z+H2kip3VH~Wm0bl>(2%suG|9F|D9=E(|cxQ|EQ_GTbZxo_D*H{$Cx+olPBFM?K}#< z(xukr#mw(uJ1QQ2#r()rsn5eqy8!b@xcV;yPxYKJQ|eEbp#6gRqqj(cwnsFtIQuE!$^KnvA6=^7={!ulc^}oly!jm3Y+?U()?ZN-YCi_&L$Yt4-$sD9 zN!5`5Q(519o>~k(T)Qe*|7SdJsCM1M{9YcXRt=@HbuD zo!T_!cPsjVM<9Ji? z(8;{{9Q{w`&F9%m5C=AHixE=5lYh*g`!8dDOS#m>FcDWX^B3~Ec@gu8Mbgf1;U~IO zJ%0f{Tzj8q{d68LO8-6ZHen(3zrV5mTR^&0|BhWQ%WX2P`x}|ReYVtB^TvzJKgn^Z z?0nAro$w!B+zf3v;*$K6hIZ36OM*6=`FBj?eLeHr*kP*N=a|2Z<7XnCw!d=sDC86elOK+C;+f3_`llhx(k@^$ZP95_Z?1wST|Au+<`{!>k|L{_&croiAVczDD z#5m@sVgnGaT}!}|f6VWJXa(iI3SVVW(Zm9+&{ghQ?ym5;%ALMaXF-YAr=2up01>VxK5|__aI59E2hO@}+aXa(N%kx(`T^?WgDy^tIztrU{ ztSl{Eg)D}Y6PmsdRaX_VIG0trOHd`JtIS(c;w-H!@fDZ5@(U*xR99=x8*+S^NmI+* zt^(IecZJJY;Pq7a$}08Oa4xozCT+ zN+&F5CMTiAuA+Pt=Y)luohaR1u*%MM6Cp#LNWx4K8t3$RjZ|WOp|?zChf)eGR`~LL z?gG(LcYcZcR;0WhXTGNpWyyL|I??UcoL6UFGizohvQ#c}W;mTUBqf&S-|Wgkfi7Pa zJU1tM=6t);z98M{MC$4V3!QcclaBOk&6$4vf|>I(WI%*nCm zI&){v%Cy7k4GVI7Q>3@2ICD^S*X(3F$|gQ3$(dV;zIVD20U4R4$@aM*FE1yzxI6_e z=gRW@vNBhBhTHDWNpxn+1KRDEJLfx#(RudloD^9=enzQ%c2dx4vU8EEfO>0LeuXQ; zos*CJ_M{+7g{A9t2=XD?NhpN7-DNLDdtK$_9?>zv-Dy{6X3U!HOvdkoPS(oG-5y_2 z2t_fK??GddOI@X2bgH);;g{n}p5$~I8E2`t&|Tzqm9s-qPzm&{w+J2S$}i0*ASV?R z=VKI==evCs83lHGinq+=v1iRA*(7I%x59Z12pDq7D&*xkCrwNV@8LxI+^jiO+2l=k z_B^-SZsqTsDNc9JWM@WBlGEh#RMn{k#pPa)can2aa#C`|Dhzco&I@jywz4&+zSqYvJsNgmfq6#`xg!BjmSvgUCF zb7ZGftjsS%Jd$g2e3O>De2C_x@9AsNmPtM_FkB_BQp{f&d1y(FZ?YgW=BAhBCOYki z1a8}G(IwV(4~{^466Ty>GqTXR2yHP!tHg-OD1|#p?e@vbFnN1;K;>uX`P1bnLmN|^ z&Por>3Stg&6(W-1dUui2<8@URxG-hqXJk>F$>E0z=Q?vHIdhVo*||yP`d;otw(?Re z3vR3!G}C5em7>(pT5)K|+`2SaJCua->~_n+&8=g3ZiXI2JT=)vqBc2MTjur@nnKVp z!JA{G)IK%1c4U;!&7KEW+N-j1o#|!QzyZS5G#RN1TKAZ)Lyb}sC^#etkK?8v?Qq($}B3_c}6l0 z!ANnUW-gll!Z{b+88YaFR||RAV=_#qJ%bk>sjL<)vZF9n$1JL(7`CWl@|64n8rQSE z9uFo9>@n=Lnac64Dsj29MFi+U!Xpg}d=92#v3qinv*0330Pq>RDYQS6EtezFsfL9= znGB%G=v_><*bbD?Hi70`kSS`YfPQP#8Cgedm$j&`qI;3m2?~6s*QrrP473c|}THfemT? zvJx@$T!s1gOsYa``^>W$JTO@dkz1T)zH+$}>(l0NUZvs@TG%H^HBjw1||5Pwo|(0)*r=}dKIc&fZNqa*dDPHqq;ooKf*6}uH=N6*o21=keRtGrTQ z!bBJ&aik+6&^p)BRs!D@%RA~RH4T79`b9_@Vx0S-RK3B*VhrN%53>*KX zq@-lIk;B+>dzOdW#$jf`UhZ-_{N$HoY|JY#hSJ33B#tI*_=A&<7@#!mU|yS2jvc?Z z)JcP~q9V9%I(_-e?KqFfJT%K-3eB2FD=*eK-Y*9iR-Vh1Ys7#u?wwWeUas~`w0Cw= zGzCY2#k7N!FSRtk+F9Yg)kXWc;D`_PZZKYHnWMEk82B`_OKCSCyC|y^XNutT%0Z5; zpP?S1mbu@OB2_&(G2G%Hr$L(SOxe{PRb~$!qhb{R}?kRurP$%LKW&0GP}cGNE1T2 ztAK--PcUNFN)E^Au_XJ}bQ3E+EJ>XT~)+n-;n~&dLfGj)>xfmk1x;Qt6_( zCCoewd*;bnOe?dKGZ3+8DQ!`C(vXg#E>pg87UWm>^w~qvkzHuV0;F7Px0ldpq905c z!W=SFpJJqB&s%`PafCqsnpOfmNa1yyZM`cIq=oXZ&}UW%<1;sfIS&ciHHA6xVhcpa z2sJ6GkW%|RS_*MMq~{Vinpe2WeHm)oWZa*I3ktXJFzramv&K#Ee|19Ux!-jB>NEaz zxj3c=5B16cYFJOk#sXocZ!W~XSRW6iZaRIKCpx=*L5>qsLZ8!y?B%4%IE<@j58`Zv znJd+qGfTywe2(#7^^-aqAS^<5CYhxvR!>LdV-d^^2<^GqSaWe6Hk>(N$-GUPWOrLU zX_2-f?2RTF_C`6r%Zt3_EAz_>GqUFuQlWG%4|5Jj#rUu)2lIb8@s`@fAPt>(gXiw= z`;6oJp1Y~V;db7^*zU6fPjY5q^wU$Ng6e#yIBR3_@f8%O&Cbi4IV;1NG;tEopP`Ey z4}V_tP;hGK8Qf~K2#59EEF!yc=SQph$xqS2d2@C~lF5*Gn1}L29~mZaIe0L&XNxCL zIBJO}P!@rR!`S7t;A7iDas7XKyLK2!jxs#rVa`HA7P7=4fwU3`kdOz@K779HjBkzh z@ME=m7-yr|nc3TsXJ^(sb9-k;mT*FX2na}!ERmSZWMmMK5Fj3rC4?{p;Ls9?5cB=7 zs=unMdmek|)$R4{bXRqC)nEVP`yb5@kP$Yka=HAd>aM%}vB?pP6k7qH1=I?{7QrK+ zR$!CkK0(kZ=%91$?J#cMXfQ$T2?i65B<-sMqmm%-Xc3L@X!u7K5jwvH9C3K(954vO z2t5ElM=YF_QhYBHbpa-}6Q+1zd! zG+|^4u@HYtHQh}j_1NiTSj2vIk4PXlFz?;NXN*m!uu*l^ogLad>#V{+5loGRv*!sB z=5y)xG<7+A+XywAC@W~F5$4I(6__GMyadgcVRBYH3_;4eUYBixhz>wMx5&Q0KM*qZ zEmWp_vqG@MA`0UZyshbMFGmFa7R&L@!;G87#`?ytIZ??6Jj9H+G%ez!2%u5 zw}+F#xMY0+tA#47V7p@Nq66R=JbB7GUs7IymlX|#sO+#AY6OvxkLsE);^_bi27M@D z-OO>TjITf`*zOE=N4DHqPeYF*F&?MHpWuSFP0|I1_L1W`!8}}VG@TBiKpux6o*3p) zjC{->*s~5iXba$!sS^SX3;H;gF!hMArn3S{e{d)$JsG+N(wN%;<~+_-E+B#X)LHFA^xAj9cm`sIw zgJwfyQLoKVH!2OnZCNUe?z2$1{c@F?d9K`sYbIGjGWQB-$K}ku%-gU{C}@E-z+}qV z*_LS{0$N~nP+h8?QX1Zp$Pcj}vR**|fDBLJ;3xZZ?-toW#M8wUC@RvE^AVyW&Hw<< z0bjs?CB*1O@SnZIo880f_!EXQ+-ypQ>-_cZ1wya3miln+f+dhHmWjN4?`X(cE#_&ra^3^P(=8mhOLu&aSSJtN!Uerdm&`O zxxXW6khCgXdl_j(3P_luMEYL`R7~3O?Xwuo66U&QCBb=gB})r#`a3~6$z>V6kwqDW z3?`GjeYLK{==#z4nRN})wKemgI4V;KREfET{%N{Rx7Y3L4F)8PuMgSBim;cxS7sF6 zh08{>?$Kz@frQ$E+^`VD7rQ$bz42Z6`XU?(KZE?^NCRkHv^_kTWl>0jU2N(XB88L4 z;gxrzBiiDy8(2F6k@~P37(Q@c!V)4UlAuq@Ey}duobJ&`OQN{g=U&i@s%jCu_OtPD zcvjVFGiM*{_}l$42->*-`{Tj<_^c}%3Lct@D+;cAeUfw|n26ZI#QEqawijgbJR(Sr zMvn-_ZCi32lsNj?neDH#Yz=J3n3s-Fg{}-K^?j~A9awIf#b&=A93>UM9yT_JN6Z@l zDHQVpbtHtKiOp;nF4`9f08r2f`WOSa=x~WJJvNeqalZ9&8|P-3*M}l(E(%3>8jpMp zj|^czC zSd)O+?BH7t_6t#+BNF9gilf!jcD6U0Asc|DJX`5D!xuKcWRiY|Aps{$Dw5qyOy&eH zy9oAL+KIi9)1-udEblZa`!JzGT(f9E@@~4&5#7yTMNU<5Ec@RoXxfghx6sqqo((j=$TvXz##k|Pu z21tFXkq%^c+#(LNQ*txqX78$INKnu6j>P#^7#0f>igniv6_5{^(D*I8R#|7y zEsE3Ahh|YE*fZ`!F6tyG6TA*uVl|ea94F18rvooIU7R$wiir-j$xYI^-JkKkz~IaV zr2UqfBMU-x0boZ+j=9H*IC958q~W-(*wCAV@P$^;ly)t5K9SBf4_$-d|d&qvnjVEuaoWCB7v z0ml&w1=BSc?_Zp{n4&hNVKpekbzwrOJzbgdC>q&OBs1h)I9Q2?M>%Dq-|)aNbmzlb zjob0002JT^CJ5amE2Ohc8A6g!xj#LhQ_>|vujw)_avc%oiWsM$Z4jjeLZ&=}{pSu2 zr-$7{e)3u_Vci31EbOUh-B&qwHDYEE^?mf#w;;o7{|2nM#aId#g}zPb(I&KLS|~MD#b+Xd;{ou>IPyyzQ9*J*3O#Fn6lm{nT1NiKBsiZHH`xA z-hSa(%fe>vk@lX#gVa@~FfXl`I?1t3@-!^^x=}D|#>|HMt|*gNr?Knii8q(e1B*W8 zWpJ?=uuWhYA7GOT!zg2F8rfHM*O>BG@2+vKXQkb^KZq!$ zX#rq5R=}K$um(O2dVstXw9C_=^YybusU`o;CMDi!2->-*S>)AK{(U$fzJ@1IQ-$Ea zXfdQfg72!nT>A6j{CqhW2>X|7KWIEEU?4nL4d%QE1v339 z6?SX_+|_u%ST4db7=6@~!8E88BfsP!gB$!XWWK{505wxAN$+TM(V>9H*$9PU0G@Iv z6PzT+(_Lq*5EpGAVZ@pTKR*lQdKMDMBI?wcA8W;G7}#itGm?}_kWmPE4oMLq-Uu|2 z<2<9$L&SM5S$bl1`KtapQfj@&5~0eMap112-v|e60^TBzFjxvpRJ`3%LH24mK%aqz z3~dvg6?A1F0IU~C?7GByc7lc|MtNp6ZHggNgUHls%&v|?V7!Xihn+}_zA#AWF9dso znlC6jDTonVT}*F+J0Mm>p=Rc-%Vtx6GpBi~BEOA!sGl+fCt%Jr&3_9!J&#zxu*kQ? zo>j>Ky-3ZL`n;mlZh=7KO{!fXkac)Y)jDXtOqZ+SzO|q}gc9%`7%f{#GC|Dh4!Q@M z4<=aZgdb;I3;xbrF^VJ;o14Jrvk+(G5lv8JYmRK9SC6QfV~{1ZvJjAj$8cz+$r4kw zXi2L%s4VLj-D|+6YzWH40;Gygg90VxJz!NEUZR`I#Y#&)hy#Ho;mnx)Dj;xGpa;D+ z0oAS00p?k#sS1D;x3XK4Oob>ZD$&9~pc?fsA5(&WTVvDRKndmQN7FAaP zC0)_g{7(vZH;8|fV@kz;9JalhR7B7-Y%5@`5)--&H_ojP4?qGHKI-n9)Tgj&a zL_~y^RXP!b2vRU=A_iD2Q(0^Wb^54Sk9Q~%=fIunL_m@$!IDN|O8nB5NUgwa2Dr0d z8ss~t938_b$gKyJndA6HP4F!wWE1b$b`B)pS^5x7Js_?ix}X-#U}3ZB4Ei8WzRem(@+GQF26^J@~b;K%Hj78j9YVj0h5>^L_DO4L`F zyHwVdH)(*0vGX9f7ZvI&0LhLn%GA7o#_|a7l$QiU$DCoEI*o#mKNu#d$5(21r4`(o zLP^0FOk60>jW%<6r-CybjMBIY>%sUSaqYm_4fb_+Qo$6K!l%=@+ouzgHY#iZ#IQG) zgd%-VOG0&zV6rmQro1tgboIMQR2L4fH|<(NhIzMir+4Ql{Md!sc4ycsEtQ*;rE1DFyM-$WsES?u>Ar(Z7&ztpHLjB^j9(eDvH$cRV`kcl)!uFilVo7K!7d zVCZSkQ4{|%qqP2-Q0cTl#kse5Sre#%wWFGs(LL({nQ^x;REKgxYC?5Lfws`tR7Ng4 zZdzx=L#XA3oJbVfMeLr{#}rxm5>mlnX=rtTriqQ_EOJCijKD*WchHIg6zGL5whBEF z)wA+KNQi*td?6Q@2tI+F*_BNwSk}82i%h7~iV2l1&7yKK>~gM@i$SI^iGh@6S*RmL zr>01W?wQ^p%B+g>gMnGyQ%y6T#1;ZAM4gLj#!#w8I0=eKoQ7m5I7@>vC40p$OHxj( zR=ag@N+{=9f>Tlnun4B-=rEH2URg67pkU225$5ExW(u7K93u;7D38gg2r-5Px3U~d=}Z;rkpLGI=33C*R;UdEtS<&91TzU@c)5Cd zKsP|9m3n#vMWr=Duo)B&)7`O61sPMx*zQnjq$g+;jBTK3Om3j)8sSVJ9(1e{h?g?3 zTw$Xi6O~lKA>c;#($ZTE12Zx;t&3UX-fhahv7+#BcvDIE+Z3@x47Q0$h)n$6?11cF11@kp#{Xhhy zMS@V(8V_i3)cZkrfX!p5?1`uKEZW$xIipQGs2*`C-JqHNRnAP_D@`CSfT35rqeD0GztOyF?%*aTP=cF7c?c_ zm5@e9FBTBfA8GK87ni&s@@@k)li|#ST&XuIBaU7UQ&gDbx~1aLOj;G!GCMQ;o-hm@>LM- z)&0~O2S#d+7W5C>o56?z&;eZv)q5a2X(y5TQm4F7h`N6Nr!>2LhIA4x+X_9**^-P|k^J?=Pu>%C_>NXtg&8fR4*hUoP|)Sh59n zT2`eXNz1BK9Ro-hAKQJJGj18NsCmkYThoh2n8gP|U)QOz<_2p}tOH3{2o;`0H58aL zv@)m#4K~FE^dDqx_L>qsAg44?t1+YOIT)Hgq9K!VTDpP#S(&;E+Q{BxAc2y2dQHUj z^^;)jUaoG_Zs#d3$21$!3yt8c?w_z^cE(lXj>8TOMjxgqjjh)xky7+?dHb`$!BG_r zlo9I;RwKf^BWd_reOlw{nbIkWT=1PZ`h1xAB(R@rC{*GVTJ72Er}N$sj`MRlp4ca< zcy@l)Y9q0D*v4DH+Wg+JCq@JP3blQoK!N@ipF8QzPFn53>l5@R$N9OOxj@An)Phg` z=;9oBZI2r0r?c_A)n=HvjgRd+Q~ZfESNzY`PWyby?|odK3-_YwN+Hi}s+EknjFD%kG$X)J0@0X-k zRenOdc}G9k@k?3vbgloP_uG92zt;Y@`oWH0^%vvwr?S7F!r#9A2io3_8`<@F`yKWi`C0s0`y1Ncj_*7o4d_76Ztbti*Dbt0xe_UTwXvZIETN}UK$BuZdVC#Rb{X5#;j*saLY5X*I zHh%54^@e_L{ryT`Mrg-x=n1>OwYTSgOWS{2JAD6f`C!Kz+K>)k#Bbi7o{xs8(;Q!> zxq&b7^94DC|MT_#A

r8yj+|9e=FrX&pSKAME%O{O#Mn`xUvsjy7IvZ-3kIXIcB- zXnQ+$h(O$r-PgYQIX?LN|3}}uYeyv~yS%c0exdDc{aSD8rFtA?&%dFk?eI%{p!-|< z@ekyT9p9qO;ePV@|259}_8%(2+VTFkTw{E+d9!bSm$g697kJungF1IV`ThTbbDzVn zJ?53a%EecHFUNeo?f!QB7cQfB>00}%+WxAxx9g<0IDY&7-#9@-wDud?enZ>8X$|$b zk^N1LiT17i+uHtZ8^11$?GL-JJ=ags*5Ci#zsU{W{ev8D$RYf1?d|v|8vFLG_w~|0 z%JDrq>3*!89Y3G7fA8;d@q2%gqwxvr!rIy2^qyq;&Yr*Z4>|Lpw%<3x)CM>7XooNB z{hzci^l0tBo_&wY`Nto#Tk!d-f0pa6T$3ZcADi9EE8#J-_`KP_$ ao&S=#){lH3c3o=!$c423nhmt3{r>?_Wq+yw literal 0 HcmV?d00001 diff --git a/testing/threads/event_builder_epoll_multhread.cxx b/testing/threads/event_builder_epoll_multhread.cxx new file mode 100644 index 0000000..aa8cc98 --- /dev/null +++ b/testing/threads/event_builder_epoll_multhread.cxx @@ -0,0 +1,351 @@ +#include +#include +#include +#include +#include +#include // for fprintf() +#include +#include +#include +#include // for close(), read() +#include // for epoll_create1(), epoll_ctl(), struct epoll_event +#include // for strncmp + +//my addition to the online guide +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +#define MAX_EVENTS 20000 + +int makeSocket() { + int sockfd; + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket failed"); + exit(EXIT_FAILURE); + } + return sockfd; +} + +void bindSocketPort(int server_fd, int port) { + struct sockaddr_in localAddr; + localAddr.sin_family = AF_INET; + localAddr.sin_addr.s_addr = INADDR_ANY; + localAddr.sin_port = htons(port); + + if (bind(server_fd, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) { + perror("bind failed"); + exit(EXIT_FAILURE); + } + printf("FD %d bound to port %d\n", server_fd, port); +} + +void startListening(int server_fd) { + if (listen(server_fd, 20000) < 0) { + perror("listen"); + exit(EXIT_FAILURE); + } + printf("FD %d listening to new connections\n", server_fd); +} + +int acceptConnection(int server_fd) { + int client_fd; + struct sockaddr_in remoteAddr; + + size_t addrlen = sizeof(remoteAddr); + if ((client_fd = accept(server_fd, (struct sockaddr *)&remoteAddr, (socklen_t *)&addrlen)) < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } else { + int flags = fcntl(client_fd, F_GETFL); + fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); + } + printf("Connection from host %s, port %d, FD %d\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port), client_fd); + return client_fd; +} + +void acceptConnectionEpollStyle(int server_fd, int &efd) { + struct sockaddr_in new_remoteAddr; + int addrlen = sizeof(struct sockaddr_in); + + while (true) { + int conn_sock = accept(server_fd, (struct sockaddr*)&new_remoteAddr, (socklen_t*)&addrlen); + + if (conn_sock == -1) { + // All incoming connections have been processed + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + break; + } else { + perror("accept"); + break; + } + } + + // make new connection non-blocking + int flags = fcntl(conn_sock, F_GETFL, 0); + fcntl(conn_sock, F_SETFL, flags | O_NONBLOCK); + + // monitor new connection for read events, always in edge triggered + struct epoll_event event; + event.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET; + event.data.fd = conn_sock; + + // Allow epoll to monitor the new connection + if (epoll_ctl(efd, EPOLL_CTL_ADD, conn_sock, &event) == -1) { + perror("epoll_ctl: conn_sock"); + break; + } + printf("Accepted epoll style connection from %s:%d from fd: %d\n", inet_ntoa(new_remoteAddr.sin_addr), ntohs(new_remoteAddr.sin_port), conn_sock); + + } +} + +void term_handler(int signal) { + printf("Terminated, received SIGNAL %d", signal); + exit(EXIT_SUCCESS); +} + +std::atomic grandtotal_kb; + + +void thradizable(int &epoll_fd, int &master_socket, int buf_size, const int &th_flag, const int thread_index) { + epoll_event events[MAX_EVENTS]; + uint64_t bytes_read = 0; + uint64_t kBytes_read = 0; + + while (true) { + if (th_flag == 1) { + grandtotal_kb += kBytes_read; + break; + } + // Time measurements + ///auto start = std::chrono::high_resolution_clock::now(); + + // Returns only the sockets for which there are events + //printf("Before wait\n"); + int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); + //printf("After wait\n"); + if (nfds == -1) { + perror("epoll_wait"); + exit(EXIT_FAILURE); + } + + // Iterate on the sockets having events + for (int i = 0; i < nfds; i++) { + //printf("Tot fds = %d reading from %d\n", nfds, i); + int fd = events[i].data.fd; + if (fd == master_socket) { + // If the activity is on the master socket, than it's a new connection request + acceptConnectionEpollStyle(master_socket, epoll_fd); + + } else if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { + // Than the client connection is closed, so I close it + printf("Closing %d", fd); + close(fd); + } else { + // Than we received data from one of the monitored sockets + char buffer[buf_size]; + int valread = 0; + //while (valread != EAGAIN) { + valread = recv(fd, &buffer, buf_size, 0); + if (valread > 0) { + //printf("[RICEVUTO]\t FROM %d\n", fd); + bytes_read += valread; + int kilos = 0; + if ((kilos = bytes_read / 1024) > 0) { + kBytes_read += kilos; + bytes_read -= (kilos * 1024); + //printf("reade bites %lu", bytes_read); + } + } + //} + + } + } + + ///auto end = std::chrono::high_resolution_clock::now(); + ///double time_taken = std::chrono::duration_cast(end - start).count(); + //time taken in milliseconds + /// + /*time_taken *= 1e-6; + total_time_taken += time_taken; + + if (total_time_taken > 3e4) { + times.push_back(total_time_taken); + tot_received_data.push_back(kBytes_read); + break; + }*/ + /// + } + +} + + +int main(int argc, char const *argv[]) { + + signal(SIGTERM, term_handler); + + + if (argc != 2) { + printf("Usage: %s portNumber \n", argv[0]); + exit(EXIT_FAILURE); + } + int port = atoi(argv[1]); + printf("Start socket port %d\n", port); + + int master_socket; + const int opt = 1; + + + master_socket = makeSocket(); + + //set master socket to allow multiple connections , + //this is just a good habit, it will work without this + if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, + sizeof(opt)) < 0 ) + { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + + bindSocketPort(master_socket, port); + startListening(master_socket); + + int flags = fcntl(master_socket, F_GETFL, 0); + fcntl(master_socket, F_SETFL, flags | O_NONBLOCK); + + epoll_event ev, events[MAX_EVENTS]; + std::array mutex_array; + std::array kBytes_read_on_descr; + + //The atomic here is used as a flag to tell the thread to stop + std::vector vThreads; + + //create the epoll instance + int epoll_fd = epoll_create1(0); + if (epoll_fd == -1) { + printf("Failed to create epoll file descriptor\n"); + exit(EXIT_FAILURE); + } + + ev.data.fd = master_socket; + // Reading events with edge triggered mode + ev.events = EPOLLIN | EPOLLEXCLUSIVE;//| EPOLLET; + + // Allowing epoll to monitor the master_socket + if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, master_socket, &ev) == -1){ + perror("epoll_ctl"); + exit(EXIT_FAILURE); + } + + std::vector sizes; + std::vector tot_received_data; + std::vector times; + + grandtotal_kb = 0; + int increment = 499; + + for (int buf_size = 1; buf_size < 1e6 + 1; ) { + switch (buf_size) { + case 500: + increment = 500; + break; + case (int) 1e3: + increment = 1e3; + break; + case (int) 5e3: + increment = 5e3; + break; + case (int) 1e4: + increment = 1e4; + break; + case (int) 5e4: + increment = 5e4; + break; + case (int) 1e5: + increment = 1e5; + break; + case (int) 5e5: + increment = 5e5; + break; + } + printf("Next increment %d with current i: %d\n", increment, buf_size); + + std::array vT; + std::array thread_flags; + + for (int t_i = 0; t_i < 4; t_i++) { + thread_flags[t_i] = 0; + vT[t_i] = std::thread(thradizable, std::ref(epoll_fd), std::ref(master_socket), buf_size, std::cref(thread_flags.at(t_i)), t_i); + } + + std::string command = ""; + std::string ref("go"); + if ( increment == 499){ + while (command != "go") { + std::cout << "Insert command: "; + std::cin >> command; + std::cout << command << std::endl; + } + } + + std::cout << "starting measurement with current buf size: " << buf_size << std::endl; + + auto start = std::chrono::high_resolution_clock::now(); + grandtotal_kb = 0; + + sleep(30); + for (int t_i = 0; t_i < 4; t_i++) { + thread_flags[t_i] = 1; + vT[t_i].join(); + } + uint64_t local_kB = grandtotal_kb; + auto end = std::chrono::high_resolution_clock::now(); + double time_taken = std::chrono::duration_cast(end - start).count(); + //time taken in milliseconds + time_taken *= 1e-6; + + times.push_back(time_taken); + sizes.push_back(buf_size); + tot_received_data.push_back(local_kB); + + buf_size += increment; + } + + + + std::ofstream fout; + fout.open("epoll_data_stats_1000_multith_TIMEOUT.csv"); + //the time is in milliseconds and the data in kbytes + fout << "buffer_size;time;total_received_data;\n"; + auto iter_sizes = sizes.begin(); + auto iter_times = times.begin(); + auto iter_data = tot_received_data.begin(); + + for ( ; (iter_sizes != sizes.end()) && (iter_times != times.end()) && (iter_data != tot_received_data.end()) ; (++iter_sizes, ++iter_times, ++iter_data) ) { + fout << *iter_sizes << ";" << *iter_times << ";" << *iter_data << ";\n"; + } + + fout.close(); + + if (close(epoll_fd)) { + printf("Failed to close epoll file descriptor"); + exit(EXIT_FAILURE); + } + + return 0; +} \ No newline at end of file diff --git a/testing/threads/prov.out b/testing/threads/prov.out new file mode 100755 index 0000000000000000000000000000000000000000..47dc96b92145ed19ce9d4716869df053327e7169 GIT binary patch literal 17752 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 literal 0 HcmV?d00001 diff --git a/testing/threads/provider.cxx b/testing/threads/provider.cxx new file mode 100644 index 0000000..a7b2038 --- /dev/null +++ b/testing/threads/provider.cxx @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int makeSocket() { + int sockfd; + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket failed"); + exit(EXIT_FAILURE); + } + return sockfd; +} + +void connectTo(int sock, const char* host, int port) { + struct sockaddr_in serv_addr; + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(host); + serv_addr.sin_port = htons(port); + + if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + perror("Connection failed"); + exit(EXIT_FAILURE); + } + + printf("Connected to %s: %d\n", host, port); +} + +int main(int argc, char* argv[]) { + + if (argc != 2) { + printf("Usage: ./prov.out timeout (ms)"); + exit(EXIT_FAILURE); + } + + int timeout = atoi(argv[1]); + //printf("Selected timeout: %f", static_cast(timeout) / 1000); + + int socket = makeSocket(); + connectTo(socket, "127.0.0.1", 7777); + + //allocating 100 megabytes of memory + uint64_t* chunky_boy = new uint64_t[67108]; + size_t chunky_boy_size = 67108 * sizeof(uint64_t); + printf("chonky size %d", static_cast(chunky_boy_size)); + + //setting memory to verify non-emptyness + memset(chunky_boy, 45678, chunky_boy_size); + + int buffer_size = 1024 * 32; + + + for ( ;;) { + + for ( int j = 0; j < chunky_boy_size; ) { + + ssize_t bytes = send(socket, reinterpret_cast(chunky_boy) + j, std::min(static_cast(chunky_boy_size) - j, buffer_size), 0); + if (timeout != 0) { + sleep(timeout); + } + j += buffer_size; + } + + //usleep(1000); + + } + + + return 0; +} \ No newline at end of file diff --git a/testing/threads/readme.md b/testing/threads/readme.md new file mode 100644 index 0000000..963c1e4 --- /dev/null +++ b/testing/threads/readme.md @@ -0,0 +1,18 @@ +# Multithreaded epoll() + +### Not a naïve implementation +To correctly set a multithreaded `epoll()` it's necessary to specifically set some flags. We'll consider level triggered mode since that's what we're using. Since we'll split the requests on different worker threads I expect the performance to scale semi-linearly with the number of workers. + +The provider implementation doesen't change. I'll spawn providers with no timeout. + +#### Results +With 4 threads we manage to see from ~1.5x to ~3x increase in performance without timeout. In prod we can maximize cpu cores using for read 8-n-1 threads, where 1 is for the main thread and n is the number of thrads used to build the full event (probably would be n=1). + +With timeout, I dont see improvement with the TIMEOUT_HARD (only 2 clients sending continuously), actually some worse perfomance in some cases. Prob this is due the EPOLLEXCLUSIVE which waste time distributing on more threads. +With the TIMEOUD (50 clients sending continuously) I get some improvement, but not comparable to the all continuous ones. That's probably because of the fact that i'm getting some sort of tradeoff between exec time in incoming connection and time needed to distribute load on threads. + +In an environment with a lot of clients and short timeouts, the approach with more than one thread is obviously preferrable for scalability reasons (50 cont + 950 1 sec timeout shows improvement already). + +In such enviroment, a multito avoid reordering.hread instance should use mutexes on read data to avoid reordering of received data. It's gonna be explained in detail during the presentations. + +(thats to study a little better) diff --git a/testing/threads/spawn_clients.sh b/testing/threads/spawn_clients.sh new file mode 100755 index 0000000..023b916 --- /dev/null +++ b/testing/threads/spawn_clients.sh @@ -0,0 +1,15 @@ +#!/bin/bash +echo "Usage: $0 host port runNumber numberOfProviders" +if [ $# -eq 1 ] +then + for i in $(seq 1 $1); + do + echo "Spawning provider number $i" + if [ $i -le 50 ] + then + ./prov.out 1& + else + ./prov.out 0& + fi + done +fi