// File: roberty65[P]bServer/frame/testClient/testBenchmark.cpp
// Function: main
int main(int argc, char **argv)
{
	if (argc < 2) {
usage:
		fprintf(stderr, "Usage: %s [-c cmd ] [ -S | A ] [-t thread-cnt] [-s pkg-size] host\n", argv[0]);
		fprintf(stderr, "    cmd=0: echo, 2: forward\n");
		fprintf(stderr, "    -S sync-req-rsp mode. default.\n");
		fprintf(stderr, "    -A async-req-rsp mode\n");
		exit(0);
	}

	int ch, sync = 1;
	while ((ch = getopt(argc, argv, "c:SAt:s:h")) != EOF) {
		switch (ch) {
		case 'c': cmd = atoi(optarg); break;
		case 'S': sync = 1; break;
		case 'A': sync = 0; break;
		case 't': tcnt = atoi(optarg); break;
		case 's': pkgSize = atoi(optarg); break;
		case 'h': goto usage;
		default: goto usage;
		}
	}

	if (optind >= argc) goto usage;
	host = strdup(argv[optind]);

	pkgSent = new long[tcnt];
	byteSent = new long[tcnt];
	pkgRspd = new long[tcnt];
	byteRspd = new long[tcnt];
	for (int i = 0; i < tcnt; ++i) pkgSent[i] = pkgRspd[i] = byteSent[i] = byteRspd[i] = 0;

	srandom(time(NULL));
	setbuf(stdout, NULL);

	pthread_t tids[tcnt];
	for (int i = 0; i < tcnt; ++i) {
		errno = pthread_create(&tids[i], NULL, sync ? sync_worker : async_worker, (void *)(long)i);
		if (errno) {
			fprintf(stdout, "create the %dth thread failed: %m\n", i);
			exit(1);
		}
	}

	long lastPkgSent = 0, lastPkgRspd = 0;
	long lastByteSent = 0, lastByteRspd = 0;
	struct timeval t1, t2;

	gettimeofday(&t1, NULL);
	while (true) {
		sleep(10);
		long thisPkgSent = 0, thisPkgRspd = 0;
		long thisByteSent = 0, thisByteRspd = 0;

		for (int i = 0; i < tcnt; ++i) {
			thisPkgSent += pkgSent[i];
			thisByteSent += byteSent[i];
			thisPkgRspd += pkgRspd[i];
			thisByteRspd += byteRspd[i];
		}

		gettimeofday(&t2, NULL);
		struct tm tmbuf, *ptm = localtime_r(&t2.tv_sec, &tmbuf);
		double ms = (t2.tv_sec - t1.tv_sec) * 1000.0 + (t2.tv_usec - t1.tv_usec) / 1000.0;

		fprintf(stdout, "%02d:%02d:%02d send %8ld %.2fpkg/s %.2fMB/s recv %8ld %.2fpkg/s %.2fMB/s\n",
			ptm->tm_hour, ptm->tm_min, ptm->tm_sec,
			thisPkgSent - lastPkgSent, 1000.0 * (thisPkgSent - lastPkgSent) / ms, 
			(thisByteSent - lastByteSent) / ms / 1000.0,
			thisPkgRspd - lastPkgRspd, 1000.0 * (thisPkgRspd - lastPkgRspd) / ms,
			(thisByteRspd - lastByteRspd) / ms / 1000.0);

		t1 = t2;
		lastPkgSent = thisPkgSent;
		lastByteSent = thisByteSent;
		lastPkgRspd = thisPkgRspd;
		lastByteRspd= thisByteRspd;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
jge 0x244f
jmp 0x23e1
movq 0x4bf0(%rip), %rax      # 0x6fd8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rdx
leaq 0x2ce7(%rip), %rsi      # 0x50e0
movb $0x0, %al
callq 0x2210
movq 0x4bd1(%rip), %rax      # 0x6fd8
movq (%rax), %rdi
leaq 0x2d12(%rip), %rsi      # 0x5123
movb $0x0, %al
callq 0x2210
movq 0x4bb9(%rip), %rax      # 0x6fd8
movq (%rax), %rdi
leaq 0x2d17(%rip), %rsi      # 0x5140
movb $0x0, %al
callq 0x2210
movq 0x4ba1(%rip), %rax      # 0x6fd8
movq (%rax), %rdi
leaq 0x2d23(%rip), %rsi      # 0x5164
movb $0x0, %al
callq 0x2210
xorl %edi, %edi
callq 0x21c0
movl $0x1, -0x18(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x2d1b(%rip), %rdx      # 0x517f
callq 0x2060
movl %eax, -0x14(%rbp)
cmpl $-0x1, %eax
je 0x2506
movl -0x14(%rbp), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, -0xf0(%rbp)
subl $0x33, %eax
ja 0x24fc
movq -0xf0(%rbp), %rax
leaq 0x2b79(%rip), %rcx      # 0x5010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x4b21(%rip), %rax      # 0x6fc8
movq (%rax), %rdi
callq 0x2240
movl %eax, 0x4cbb(%rip)      # 0x7170
jmp 0x2501
movl $0x1, -0x18(%rbp)
jmp 0x2501
movl $0x0, -0x18(%rbp)
jmp 0x2501
movq 0x4af8(%rip), %rax      # 0x6fc8
movq (%rax), %rdi
callq 0x2240
movl %eax, 0x4c96(%rip)      # 0x7174
jmp 0x2501
movq 0x4ae1(%rip), %rax      # 0x6fc8
movq (%rax), %rdi
callq 0x2240
movl %eax, 0x4c83(%rip)      # 0x7178
jmp 0x2501
jmp 0x23e1
jmp 0x23e1
jmp 0x2456
movq 0x4ad3(%rip), %rax      # 0x6fe0
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jl 0x2519
jmp 0x23e1
movq -0x10(%rbp), %rax
movq 0x4abc(%rip), %rcx      # 0x6fe0
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x22a0
movq %rax, 0x4c49(%rip)      # 0x7180
movslq 0x4c36(%rip), %rax      # 0x7174
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, 0x4c32(%rip)      # 0x7198
movslq 0x4c07(%rip), %rax      # 0x7174
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, 0x4c0b(%rip)      # 0x71a0
movslq 0x4bd8(%rip), %rax      # 0x7174
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, 0x4be4(%rip)      # 0x71a8
movslq 0x4ba9(%rip), %rax      # 0x7174
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, 0x4bbd(%rip)      # 0x71b0
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl 0x4b71(%rip), %eax      # 0x7174
jge 0x265c
movq 0x4ba4(%rip), %rax      # 0x71b0
movslq -0x1c(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movq (%rax,%rcx,8), %rdx
movq 0x4b7d(%rip), %rax      # 0x71a0
movslq -0x1c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq (%rax,%rcx,8), %rdx
movq 0x4b72(%rip), %rax      # 0x71a8
movslq -0x1c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq (%rax,%rcx,8), %rdx
movq 0x4b4f(%rip), %rax      # 0x7198
movslq -0x1c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x25fa
xorl %eax, %eax
movl %eax, %edi
movq %rdi, -0x100(%rbp)
callq 0x2170
movl %eax, %edi
callq 0x2070
movq -0x100(%rbp), %rsi
movq 0x4937(%rip), %rax      # 0x6fb8
movq (%rax), %rdi
callq 0x2200
movl 0x4ae5(%rip), %eax      # 0x7174
movq %rsp, %rcx
movq %rcx, -0x28(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xf8(%rbp)
movq %rcx, %rsp
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl 0x4aae(%rip), %eax      # 0x7174
jge 0x2778
movq -0xf8(%rbp), %rax
movslq -0x34(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x108(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x26fb
leaq 0x31e(%rip), %rax       # 0x2a10
movq %rax, -0x110(%rbp)
jmp 0x270b
leaq 0x52e(%rip), %rax       # 0x2c30
movq %rax, -0x110(%rbp)
jmp 0x270b
movq -0x108(%rbp), %rdi
movq -0x110(%rbp), %rdx
movslq -0x34(%rbp), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x2280
movl %eax, -0x114(%rbp)
callq 0x2040
movl -0x114(%rbp), %ecx
movl %ecx, (%rax)
callq 0x2040
cmpl $0x0, (%rax)
je 0x2768
movq 0x486e(%rip), %rax      # 0x6fb8
movq (%rax), %rdi
movl -0x34(%rbp), %edx
leaq 0x2a32(%rip), %rsi      # 0x5189
movb $0x0, %al
callq 0x2210
movl $0x1, %edi
callq 0x21c0
jmp 0x276a
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x26bd
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
leaq -0x68(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2260
jmp 0x27a7
movl $0xa, %edi
callq 0x2130
movq $0x0, -0x80(%rbp)
movq $0x0, -0x88(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
cmpl 0x4984(%rip), %eax      # 0x7174
jge 0x2884
movq 0x499b(%rip), %rax      # 0x7198
movslq -0x9c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq 0x4989(%rip), %rax      # 0x71a0
movslq -0x9c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
addq -0x90(%rbp), %rax
movq %rax, -0x90(%rbp)
movq 0x4971(%rip), %rax      # 0x71a8
movslq -0x9c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
addq -0x88(%rbp), %rax
movq %rax, -0x88(%rbp)
movq 0x4959(%rip), %rax      # 0x71b0
movslq -0x9c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
addq -0x98(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x27e4
leaq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2260
leaq -0x78(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x20e0
movq %rax, -0xe0(%rbp)
movq -0x78(%rbp), %rax
subq -0x68(%rbp), %rax
cvtsi2sd %rax, %xmm0
movq -0x70(%rbp), %rax
subq -0x60(%rbp), %rax
cvtsi2sd %rax, %xmm1
movsd 0x273e(%rip), %xmm2     # 0x5008
divsd %xmm2, %xmm1
movsd 0x2732(%rip), %xmm2     # 0x5008
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xe8(%rbp)
movq 0x46cb(%rip), %rax      # 0x6fb8
movq (%rax), %rdi
movq -0xe0(%rbp), %rax
movl 0x8(%rax), %edx
movq -0xe0(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0xe0(%rbp), %rax
movl (%rax), %r8d
movq -0x80(%rbp), %r9
subq -0x40(%rbp), %r9
movq -0x80(%rbp), %rax
subq -0x40(%rbp), %rax
cvtsi2sd %rax, %xmm1
movsd 0x26dd(%rip), %xmm0     # 0x5008
mulsd %xmm1, %xmm0
divsd -0xe8(%rbp), %xmm0
movq -0x90(%rbp), %rax
subq -0x50(%rbp), %rax
cvtsi2sd %rax, %xmm1
divsd -0xe8(%rbp), %xmm1
movsd 0x26b1(%rip), %xmm2     # 0x5008
divsd %xmm2, %xmm1
movq -0x88(%rbp), %rax
subq -0x48(%rbp), %rax
movq -0x88(%rbp), %rsi
subq -0x48(%rbp), %rsi
cvtsi2sd %rsi, %xmm3
movsd 0x268a(%rip), %xmm2     # 0x5008
mulsd %xmm3, %xmm2
divsd -0xe8(%rbp), %xmm2
movq -0x98(%rbp), %rsi
subq -0x58(%rbp), %rsi
cvtsi2sd %rsi, %xmm3
divsd -0xe8(%rbp), %xmm3
movsd 0x265e(%rip), %xmm4     # 0x5008
divsd %xmm4, %xmm3
leaq 0x27f7(%rip), %rsi      # 0x51ac
subq $0x10, %rsp
movq %rax, (%rsp)
movb $0x4, %al
callq 0x2210
addq $0x10, %rsp
movq -0x78(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x27a5
nopw %cs:(%rax,%rax)