| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- class Const {
- public static var HOST = new neko.net.Host("localhost");
- public static var PORT = 1234;
- public static var LOOPS = 3000;
- public static var CLIENTS = 200;
- public static var SOCKETS = 5;
- public static var SERVERS = 16;
- public static var USE_POLL = true;
- }
- class Task {
- var t : neko.vm.Thread;
- public var done : Bool;
- public function new() {
- t = neko.vm.Thread.create(run);
- }
- function run() {
- try {
- loop();
- } catch( e : Dynamic ) {
- neko.Lib.print(e);
- neko.Lib.print("\n");
- neko.Lib.print(haxe.Stack.toString(haxe.Stack.exceptionStack()));
- neko.Lib.print("\n");
- }
- done = true;
- }
- function loop() {
- // TODO
- }
- }
- class Client extends Task {
- public var time : Float;
- public function new() {
- time = 0;
- super();
- }
- function loop() {
- var sockets = new Array();
- for( i in 0...Const.SOCKETS ) {
- var s = new neko.net.Socket();
- while( true ) {
- var ok = true;
- try {
- s.connect(Const.HOST,Const.PORT);
- } catch( e : Dynamic ) {
- ok = false;
- neko.Lib.print("C");
- neko.Sys.sleep(0.1);
- }
- if( ok )
- break;
- }
- sockets.push(s);
- }
- var event = Math.round(Const.LOOPS / Const.SOCKETS);
- var t = neko.Sys.time();
- for( i in 0...Const.LOOPS ) {
- var c = i % 256;
- var k = Std.random(sockets.length);
- var s = sockets[k];
- s.output.writeChar(c);
- if( s.input.readChar() != c ) throw "???";
- if( k > 0 && k == sockets.length - 1 && Std.random(event) == 0 ) {
- neko.Lib.print("x");
- s.close();
- sockets.remove(s);
- }
- }
- time = neko.Sys.time() - t;
- for( s in sockets ) {
- neko.Lib.print("x");
- s.close();
- }
- }
- }
- class ServerSelect extends Task {
- var sockets : Array<neko.net.Socket>;
- public function new(size) {
- sockets = new Array();
- super();
- }
- public function addClient(sock) {
- t.sendMessage(sock);
- }
- function loop() {
- var s : neko.net.Socket = neko.vm.Thread.readMessage(true);
- sockets.push(s);
- while( true ) {
- for( s in neko.net.Socket.select(sockets,null,null,0.1).read ) {
- try {
- s.output.writeChar(s.input.readChar());
- } catch( e : Dynamic ) {
- neko.Lib.print("-");
- sockets.remove(s);
- s.close();
- }
- }
- while( true ) {
- var s : neko.net.Socket = neko.vm.Thread.readMessage(false);
- if( s == null ) {
- if( sockets.length != 0 )
- break;
- done = true;
- s = neko.vm.Thread.readMessage(true);
- done = false;
- }
- sockets.push(s);
- neko.Lib.print("+");
- }
- }
- }
- }
- class ServerEvents extends Task {
- var sockets : Array<neko.net.Socket>;
- var poll : neko.net.Poll;
- public function new(size) {
- sockets = new Array();
- poll = new neko.net.Poll(size);
- super();
- }
- public function addClient(sock) {
- t.sendMessage(sock);
- }
- function loop() {
- var toremove = new Array();
- while( true ) {
- poll.events(0.1);
- var i = 0;
- var idx = poll.readIndexes;
- while( true ) {
- var s = sockets[idx[i]];
- if( s == null )
- break;
- i++;
- try {
- s.output.writeChar(s.input.readChar());
- } catch( e : Dynamic ) {
- neko.Lib.print("-");
- toremove.push(s);
- }
- }
- if( toremove.length > 0 ) {
- for( s in toremove ) {
- sockets.remove(s);
- s.close();
- }
- poll.prepare(sockets,[]);
- toremove = new Array();
- }
- var mod = false;
- while( true ) {
- var s : neko.net.Socket = neko.vm.Thread.readMessage(false);
- if( s == null ) {
- if( sockets.length != 0 )
- break;
- done = true;
- s = neko.vm.Thread.readMessage(true);
- done = false;
- }
- sockets.push(s);
- mod = true;
- neko.Lib.print("+");
- }
- if( mod )
- poll.prepare(sockets,[]);
- }
- }
- }
- class MTNetwork {
- static var cputime : Void -> Float = neko.Lib.load("std","sys_cpu_time",0);
- static function main() {
- var size = Math.round(Const.CLIENTS * Const.SOCKETS / Const.SERVERS);
- trace("Starting on "+Const.HOST.toString()+":"+Const.PORT);
- trace("Socket per server "+size);
- var cpu = cputime();
- var time = neko.Sys.time();
- var sock = new neko.net.Socket();
- sock.bind(Const.HOST,Const.PORT);
- sock.listen(Const.CLIENTS * Const.SOCKETS);
- var servers = new Array<{ done : Bool, addClient : neko.net.Socket -> Void }>();
- for( i in 0...Const.SERVERS )
- if( Const.USE_POLL )
- servers.push(new ServerEvents(size));
- else
- servers.push(new ServerSelect(size));
- var clients = new Array();
- for( i in 0...Const.CLIENTS )
- clients.push(new Client());
- for( cid in 0...Const.CLIENTS * Const.SOCKETS ) {
- var s = sock.accept();
- s.setBlocking(false);
- servers[cid%servers.length].addClient(s);
- }
- var done = false;
- while( !done ) {
- done = true;
- for( c in clients )
- if( !c.done ) {
- done = false;
- break;
- }
- if( !done ) {
- neko.Sys.sleep(0.5);
- continue;
- }
- for( s in servers )
- if( !s.done ) {
- done = false;
- break;
- }
- neko.Sys.sleep(0.5);
- }
- var cpu2 = cputime();
- var time2 = neko.Sys.time();
- var st = 0.;
- var min = 1000.;
- var max = 0.;
- for( c in clients ) {
- st += c.time;
- if( c.time < min ) min = c.time;
- if( c.time > max ) max = c.time;
- }
- neko.Lib.print("\n");
- trace("AVG = "+(st / (Const.CLIENTS * Const.LOOPS)));
- trace("MIN = "+(min / Const.LOOPS));
- trace("MAX = "+(max / Const.LOOPS));
- trace("CPU = "+((cpu2 - cpu) / Const.LOOPS));
- trace("TOTAL TIME = "+((time2 - time) / Const.LOOPS));
- trace("DONE");
- }
- }
|