// File: kentcz[P]rapl-tools/AppPowerMeter.cpp
// Function: main
int main(int argc, char *argv[]) {

	Rapl *rapl = new Rapl();
	int ms_pause = 100;       // sample every 100ms
	std::ofstream outfile ("rapl.csv", std::ios::out | std::ios::trunc);

	pid_t child_pid = fork();
	if (child_pid >= 0) { //fork successful
		if (child_pid == 0) { // child process
			//printf("CHILD: child pid=%d\n", getpid());
			int exec_status = execvp(argv[1], argv+1);
			if (exec_status) {
				std::cerr << "execv failed with error " 
					<< errno << " "
					<< strerror(errno) << std::endl;
			}
		} else {              // parent process
			
			int status = 1;
			waitpid(child_pid, &status, WNOHANG);	
			while (status) {
				
				usleep(ms_pause * 1000);

				// rapl sample
				rapl->sample();
				outfile << rapl->pkg_current_power() << ","
					<< rapl->pp0_current_power() << ","
					<< rapl->pp1_current_power() << ","
					<< rapl->dram_current_power() << ","
					<< rapl->total_time() << std::endl;

				waitpid(child_pid, &status, WNOHANG);	
			}
			wait(&status); /* wait for child to exit, and store its status */
			std::cout << "PARENT: Child's exit code is: " 
				<< WEXITSTATUS(status) 
				<< std::endl;
			
			std::cout << std::endl 
				<< "\tTotal Energy:\t" << rapl->pkg_total_energy() << " J" << std::endl
				<< "\tAverage Power:\t" << rapl->pkg_average_power() << " W" << std::endl
				<< "\tTime:\t" << rapl->total_time() << " sec" << std::endl;
		}
	} else {
		std::cerr << "fork failed" << std::endl;
		return 1;
	}
	
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x360, %rsp            # imm = 0x360
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x120, %edi            # imm = 0x120
callq 0x2110
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x240(%rbp)
callq 0x2960
jmp 0x2387
movq -0x240(%rbp), %rax
movq %rax, -0x18(%rbp)
movl $0x64, -0x28(%rbp)
movl $0x10, %edi
movl $0x20, %esi
callq 0x2940
movl %eax, %edx
leaq -0x228(%rbp), %rdi
leaq 0x1c4c(%rip), %rsi      # 0x4004
callq 0x2140
callq 0x2040
movl %eax, -0x22c(%rbp)
cmpl $0x0, -0x22c(%rbp)
jl 0x28bd
cmpl $0x0, -0x22c(%rbp)
jne 0x24dd
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x8, %rsi
callq 0x20b0
movl %eax, -0x230(%rbp)
cmpl $0x0, -0x230(%rbp)
je 0x24d8
movq 0x3bdf(%rip), %rdi      # 0x5ff0
leaq 0x1bf5(%rip), %rsi      # 0x400d
callq 0x2100
movq %rax, -0x248(%rbp)
jmp 0x2426
callq 0x2030
movq -0x248(%rbp), %rdi
movl (%rax), %esi
callq 0x21d0
movq %rax, -0x250(%rbp)
jmp 0x2442
movq -0x250(%rbp), %rdi
leaq 0x1bf5(%rip), %rsi      # 0x4045
callq 0x2100
movq %rax, -0x258(%rbp)
jmp 0x245e
callq 0x2030
movl (%rax), %edi
callq 0x2050
movq -0x258(%rbp), %rdi
movq %rax, %rsi
callq 0x2100
movq %rax, -0x260(%rbp)
jmp 0x2482
movq -0x260(%rbp), %rdi
movq 0x3b28(%rip), %rsi      # 0x5fb8
callq 0x2130
jmp 0x2497
jmp 0x24d8
movq -0x240(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x120, %esi            # imm = 0x120
callq 0x2120
jmp 0x292a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x228(%rbp), %rdi
callq 0x21a0
jmp 0x292a
jmp 0x28bb
movl $0x1, -0x234(%rbp)
movl -0x22c(%rbp), %edi
leaq -0x234(%rbp), %rsi
movl $0x1, %edx
callq 0x20c0
jmp 0x2500
jmp 0x2502
cmpl $0x0, -0x234(%rbp)
je 0x26bd
movl -0x28(%rbp), %eax
imull $0x3e8, %eax, %edi      # imm = 0x3E8
callq 0x2180
jmp 0x251f
movq -0x18(%rbp), %rdi
callq 0x2df0
jmp 0x252a
movq -0x18(%rbp), %rdi
callq 0x30f0
movsd %xmm0, -0x268(%rbp)
jmp 0x253d
movsd -0x268(%rbp), %xmm0
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x270(%rbp)
jmp 0x255a
movq -0x270(%rbp), %rdi
leaq 0x1abe(%rip), %rsi      # 0x4026
callq 0x2100
movq %rax, -0x278(%rbp)
jmp 0x2576
movq -0x18(%rbp), %rdi
callq 0x3140
movsd %xmm0, -0x280(%rbp)
jmp 0x2589
movsd -0x280(%rbp), %xmm0
movq -0x278(%rbp), %rdi
callq 0x2200
movq %rax, -0x288(%rbp)
jmp 0x25a6
movq -0x288(%rbp), %rdi
leaq 0x1a72(%rip), %rsi      # 0x4026
callq 0x2100
movq %rax, -0x290(%rbp)
jmp 0x25c2
movq -0x18(%rbp), %rdi
callq 0x31a0
movsd %xmm0, -0x298(%rbp)
jmp 0x25d5
movsd -0x298(%rbp), %xmm0
movq -0x290(%rbp), %rdi
callq 0x2200
movq %rax, -0x2a0(%rbp)
jmp 0x25f2
movq -0x2a0(%rbp), %rdi
leaq 0x1a26(%rip), %rsi      # 0x4026
callq 0x2100
movq %rax, -0x2a8(%rbp)
jmp 0x260e
movq -0x18(%rbp), %rdi
callq 0x3200
movsd %xmm0, -0x2b0(%rbp)
jmp 0x2621
movsd -0x2b0(%rbp), %xmm0
movq -0x2a8(%rbp), %rdi
callq 0x2200
movq %rax, -0x2b8(%rbp)
jmp 0x263e
movq -0x2b8(%rbp), %rdi
leaq 0x19da(%rip), %rsi      # 0x4026
callq 0x2100
movq %rax, -0x2c0(%rbp)
jmp 0x265a
movq -0x18(%rbp), %rdi
callq 0x32f0
movsd %xmm0, -0x2c8(%rbp)
jmp 0x266d
movsd -0x2c8(%rbp), %xmm0
movq -0x2c0(%rbp), %rdi
callq 0x2200
movq %rax, -0x2d0(%rbp)
jmp 0x268a
movq -0x2d0(%rbp), %rdi
movq 0x3920(%rip), %rsi      # 0x5fb8
callq 0x2130
jmp 0x269f
movl -0x22c(%rbp), %edi
leaq -0x234(%rbp), %rsi
movl $0x1, %edx
callq 0x20c0
jmp 0x26b8
jmp 0x2502
leaq -0x234(%rbp), %rdi
callq 0x2170
jmp 0x26cb
movq 0x38f6(%rip), %rdi      # 0x5fc8
leaq 0x194f(%rip), %rsi      # 0x4028
callq 0x2100
movq %rax, -0x2d8(%rbp)
jmp 0x26e7
movq -0x2d8(%rbp), %rdi
movzbl -0x233(%rbp), %esi
callq 0x21d0
movq %rax, -0x2e0(%rbp)
jmp 0x2703
movq -0x2e0(%rbp), %rdi
movq 0x38a7(%rip), %rsi      # 0x5fb8
callq 0x2130
jmp 0x2718
movq 0x38a9(%rip), %rdi      # 0x5fc8
movq 0x3892(%rip), %rsi      # 0x5fb8
callq 0x2130
movq %rax, -0x2e8(%rbp)
jmp 0x2734
movq -0x2e8(%rbp), %rdi
leaq 0x1905(%rip), %rsi      # 0x4047
callq 0x2100
movq %rax, -0x2f0(%rbp)
jmp 0x2750
movq -0x18(%rbp), %rdi
callq 0x32a0
movsd %xmm0, -0x2f8(%rbp)
jmp 0x2763
movsd -0x2f8(%rbp), %xmm0
movq -0x2f0(%rbp), %rdi
callq 0x2200
movq %rax, -0x300(%rbp)
jmp 0x2780
movq -0x300(%rbp), %rdi
leaq 0x18c9(%rip), %rsi      # 0x4057
callq 0x2100
movq %rax, -0x308(%rbp)
jmp 0x279c
movq -0x308(%rbp), %rdi
movq 0x380e(%rip), %rsi      # 0x5fb8
callq 0x2130
movq %rax, -0x310(%rbp)
jmp 0x27b8
movq -0x310(%rbp), %rdi
leaq 0x1894(%rip), %rsi      # 0x405a
callq 0x2100
movq %rax, -0x318(%rbp)
jmp 0x27d4
movq -0x18(%rbp), %rdi
callq 0x3260
movsd %xmm0, -0x320(%rbp)
jmp 0x27e7
movsd -0x320(%rbp), %xmm0
movq -0x318(%rbp), %rdi
callq 0x2200
movq %rax, -0x328(%rbp)
jmp 0x2804
movq -0x328(%rbp), %rdi
leaq 0x1859(%rip), %rsi      # 0x406b
callq 0x2100
movq %rax, -0x330(%rbp)
jmp 0x2820
movq -0x330(%rbp), %rdi
movq 0x378a(%rip), %rsi      # 0x5fb8
callq 0x2130
movq %rax, -0x338(%rbp)
jmp 0x283c
movq -0x338(%rbp), %rdi
leaq 0x1824(%rip), %rsi      # 0x406e
callq 0x2100
movq %rax, -0x340(%rbp)
jmp 0x2858
movq -0x18(%rbp), %rdi
callq 0x32f0
movsd %xmm0, -0x348(%rbp)
jmp 0x286b
movsd -0x348(%rbp), %xmm0
movq -0x340(%rbp), %rdi
callq 0x2200
movq %rax, -0x350(%rbp)
jmp 0x2888
movq -0x350(%rbp), %rdi
leaq 0x17e0(%rip), %rsi      # 0x4076
callq 0x2100
movq %rax, -0x358(%rbp)
jmp 0x28a4
movq -0x358(%rbp), %rdi
movq 0x3706(%rip), %rsi      # 0x5fb8
callq 0x2130
jmp 0x28b9
jmp 0x28bb
jmp 0x2901
movq 0x372c(%rip), %rdi      # 0x5ff0
leaq 0x17b0(%rip), %rsi      # 0x407b
callq 0x2100
movq %rax, -0x360(%rbp)
jmp 0x28d9
movq -0x360(%rbp), %rdi
movq 0x36d1(%rip), %rsi      # 0x5fb8
callq 0x2130
jmp 0x28ee
movl $0x1, -0x4(%rbp)
movl $0x1, -0x238(%rbp)
jmp 0x2912
movl $0x0, -0x4(%rbp)
movl $0x1, -0x238(%rbp)
leaq -0x228(%rbp), %rdi
callq 0x21a0
movl -0x4(%rbp), %eax
addq $0x360, %rsp            # imm = 0x360
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x21f0
nopw %cs:(%rax,%rax)
nopl (%rax)