MTNetwork.hx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. class Const {
  2. public static var HOST = new neko.net.Host("localhost");
  3. public static var PORT = 1234;
  4. public static var LOOPS = 3000;
  5. public static var CLIENTS = 200;
  6. public static var SOCKETS = 5;
  7. public static var SERVERS = 16;
  8. public static var USE_POLL = true;
  9. }
  10. class Task {
  11. var t : neko.vm.Thread;
  12. public var done : Bool;
  13. public function new() {
  14. t = neko.vm.Thread.create(run);
  15. }
  16. function run() {
  17. try {
  18. loop();
  19. } catch( e : Dynamic ) {
  20. neko.Lib.print(e);
  21. neko.Lib.print("\n");
  22. neko.Lib.print(haxe.Stack.toString(haxe.Stack.exceptionStack()));
  23. neko.Lib.print("\n");
  24. }
  25. done = true;
  26. }
  27. function loop() {
  28. // TODO
  29. }
  30. }
  31. class Client extends Task {
  32. public var time : Float;
  33. public function new() {
  34. time = 0;
  35. super();
  36. }
  37. function loop() {
  38. var sockets = new Array();
  39. for( i in 0...Const.SOCKETS ) {
  40. var s = new neko.net.Socket();
  41. while( true ) {
  42. var ok = true;
  43. try {
  44. s.connect(Const.HOST,Const.PORT);
  45. } catch( e : Dynamic ) {
  46. ok = false;
  47. neko.Lib.print("C");
  48. neko.Sys.sleep(0.1);
  49. }
  50. if( ok )
  51. break;
  52. }
  53. sockets.push(s);
  54. }
  55. var event = Math.round(Const.LOOPS / Const.SOCKETS);
  56. var t = neko.Sys.time();
  57. for( i in 0...Const.LOOPS ) {
  58. var c = i % 256;
  59. var k = Std.random(sockets.length);
  60. var s = sockets[k];
  61. s.output.writeChar(c);
  62. if( s.input.readChar() != c ) throw "???";
  63. if( k > 0 && k == sockets.length - 1 && Std.random(event) == 0 ) {
  64. neko.Lib.print("x");
  65. s.close();
  66. sockets.remove(s);
  67. }
  68. }
  69. time = neko.Sys.time() - t;
  70. for( s in sockets ) {
  71. neko.Lib.print("x");
  72. s.close();
  73. }
  74. }
  75. }
  76. class ServerSelect extends Task {
  77. var sockets : Array<neko.net.Socket>;
  78. public function new(size) {
  79. sockets = new Array();
  80. super();
  81. }
  82. public function addClient(sock) {
  83. t.sendMessage(sock);
  84. }
  85. function loop() {
  86. var s : neko.net.Socket = neko.vm.Thread.readMessage(true);
  87. sockets.push(s);
  88. while( true ) {
  89. for( s in neko.net.Socket.select(sockets,null,null,0.1).read ) {
  90. try {
  91. s.output.writeChar(s.input.readChar());
  92. } catch( e : Dynamic ) {
  93. neko.Lib.print("-");
  94. sockets.remove(s);
  95. s.close();
  96. }
  97. }
  98. while( true ) {
  99. var s : neko.net.Socket = neko.vm.Thread.readMessage(false);
  100. if( s == null ) {
  101. if( sockets.length != 0 )
  102. break;
  103. done = true;
  104. s = neko.vm.Thread.readMessage(true);
  105. done = false;
  106. }
  107. sockets.push(s);
  108. neko.Lib.print("+");
  109. }
  110. }
  111. }
  112. }
  113. class ServerEvents extends Task {
  114. var sockets : Array<neko.net.Socket>;
  115. var poll : neko.net.Poll;
  116. public function new(size) {
  117. sockets = new Array();
  118. poll = new neko.net.Poll(size);
  119. super();
  120. }
  121. public function addClient(sock) {
  122. t.sendMessage(sock);
  123. }
  124. function loop() {
  125. var toremove = new Array();
  126. while( true ) {
  127. poll.events(0.1);
  128. var i = 0;
  129. var idx = poll.readIndexes;
  130. while( true ) {
  131. var s = sockets[idx[i]];
  132. if( s == null )
  133. break;
  134. i++;
  135. try {
  136. s.output.writeChar(s.input.readChar());
  137. } catch( e : Dynamic ) {
  138. neko.Lib.print("-");
  139. toremove.push(s);
  140. }
  141. }
  142. if( toremove.length > 0 ) {
  143. for( s in toremove ) {
  144. sockets.remove(s);
  145. s.close();
  146. }
  147. poll.prepare(sockets,[]);
  148. toremove = new Array();
  149. }
  150. var mod = false;
  151. while( true ) {
  152. var s : neko.net.Socket = neko.vm.Thread.readMessage(false);
  153. if( s == null ) {
  154. if( sockets.length != 0 )
  155. break;
  156. done = true;
  157. s = neko.vm.Thread.readMessage(true);
  158. done = false;
  159. }
  160. sockets.push(s);
  161. mod = true;
  162. neko.Lib.print("+");
  163. }
  164. if( mod )
  165. poll.prepare(sockets,[]);
  166. }
  167. }
  168. }
  169. class MTNetwork {
  170. static var cputime : Void -> Float = neko.Lib.load("std","sys_cpu_time",0);
  171. static function main() {
  172. var size = Math.round(Const.CLIENTS * Const.SOCKETS / Const.SERVERS);
  173. trace("Starting on "+Const.HOST.toString()+":"+Const.PORT);
  174. trace("Socket per server "+size);
  175. var cpu = cputime();
  176. var time = neko.Sys.time();
  177. var sock = new neko.net.Socket();
  178. sock.bind(Const.HOST,Const.PORT);
  179. sock.listen(Const.CLIENTS * Const.SOCKETS);
  180. var servers = new Array<{ done : Bool, addClient : neko.net.Socket -> Void }>();
  181. for( i in 0...Const.SERVERS )
  182. if( Const.USE_POLL )
  183. servers.push(new ServerEvents(size));
  184. else
  185. servers.push(new ServerSelect(size));
  186. var clients = new Array();
  187. for( i in 0...Const.CLIENTS )
  188. clients.push(new Client());
  189. for( cid in 0...Const.CLIENTS * Const.SOCKETS ) {
  190. var s = sock.accept();
  191. s.setBlocking(false);
  192. servers[cid%servers.length].addClient(s);
  193. }
  194. var done = false;
  195. while( !done ) {
  196. done = true;
  197. for( c in clients )
  198. if( !c.done ) {
  199. done = false;
  200. break;
  201. }
  202. if( !done ) {
  203. neko.Sys.sleep(0.5);
  204. continue;
  205. }
  206. for( s in servers )
  207. if( !s.done ) {
  208. done = false;
  209. break;
  210. }
  211. neko.Sys.sleep(0.5);
  212. }
  213. var cpu2 = cputime();
  214. var time2 = neko.Sys.time();
  215. var st = 0.;
  216. var min = 1000.;
  217. var max = 0.;
  218. for( c in clients ) {
  219. st += c.time;
  220. if( c.time < min ) min = c.time;
  221. if( c.time > max ) max = c.time;
  222. }
  223. neko.Lib.print("\n");
  224. trace("AVG = "+(st / (Const.CLIENTS * Const.LOOPS)));
  225. trace("MIN = "+(min / Const.LOOPS));
  226. trace("MAX = "+(max / Const.LOOPS));
  227. trace("CPU = "+((cpu2 - cpu) / Const.LOOPS));
  228. trace("TOTAL TIME = "+((time2 - time) / Const.LOOPS));
  229. trace("DONE");
  230. }
  231. }