// File: /workspace/github_c_makefile_star2_O0/mvermeulen[P]wspy/wspy.c
// Function: main
int main(int argc,char *const argv[],char *const envp[]){
  int i;
  int status;
  struct rusage rusage;
  struct counter_group *cgroup;
  outfile = stdout;
  num_procs = get_nprocs();
  clocks_per_second = sysconf(_SC_CLK_TCK);
  
  if (parse_options(argc,argv)){
      fatal("usage: %s -[abcistv][-o <file>] <cmd><args>...\n"
	    "\t--per-core or -a          - metrics per core\n"
	    "\t--rusage or -r            - show getrusage(2) information\n"
	    "\t--tree <file>             - create CSV of processes\n"
	    "\t--tree-cmdline            - record full command lines\n"
	    "\t--tree-vmsize             - virtual memory size\n"
	    "\t-o <file>                 - send output to file\n"
	    "\t--csv                     - create csv output\n"
	    "\t--interval <sec>          - read every <sec> seconds\n"
	    "\t--verbose or -v           - print verbose information\n"
	    "\n"
	    "\t--software or -s          - software counters\n"
	    "\t--ipc or i                - IPC counters\n"
	    "\t--branch or -b            - branch counters\n"
	    "\t--dcache                  - L1 dcache counters\n"
	    "\t--icache                  - L1 icache counters\n"
	    "\t--cache2 or -c            - L2 cache counters\n"
	    "\t--cache3                  - L3 cache counters\n"
	    "\t--memory                  - memory counters\n"
	    "\t--opcache                 - opcache counters\n"
	    "\t--tlb                     - TLB counters\n"
	    "\t--topdown or -t           - topdown counters, level 1\n"
	    "\t--topdown2                - topdown counters, level 2\n"
	    "\t--topdown-frontend        - topdown related to fe\n"
	    "\t--topdown-optlb           - topdown related to opcache, dtlb\n"
	    ,argv[0]);
  }

  if (inventory_cpu() != 0){
    fatal("unable to query CPU information\n");
  }

  check_nmi_watchdog();

#if AMDGPU
  gpu_info_initialize();
#endif

  // parse the event tables
  setup_raw_events();

  // set up either system-wide or core-specific counters
  if (aflag){
    for (i=0;i<cpu_info->num_cores;i++){
      if (cpu_info->coreinfo[i].is_available &&
	  ((cpu_info->coreinfo[i].vendor == CORE_AMD_ZEN)||(cpu_info->coreinfo[i].vendor == CORE_AMD_ZEN5)||(cpu_info->coreinfo[i].vendor == CORE_INTEL_CORE))){
	setup_counter_groups(&cpu_info->coreinfo[i].core_specific_counters);
      }
    }
  } else {
    setup_counter_groups(&cpu_info->systemwide_counters);
  }
  // software counters are only system-wide
  if (counter_mask & COUNTER_SOFTWARE){
    if (cgroup = software_counter_group("software")){
      cgroup->next = cpu_info->systemwide_counters;
      cpu_info->systemwide_counters = cgroup;
    }
  }

  // set up core-specific and system-wide counters
  for (i=0;i<cpu_info->num_cores;i++){
    if (cpu_info->coreinfo[i].core_specific_counters)
      setup_counters(cpu_info->coreinfo[i].core_specific_counters);
  }
  setup_counters(cpu_info->systemwide_counters);

  // start core-specific and system-wide counters
  for (i=0;i<cpu_info->num_cores;i++){
    if (cpu_info->coreinfo[i].core_specific_counters)
      start_counters(cpu_info->coreinfo[i].core_specific_counters);
  }
  start_counters(cpu_info->systemwide_counters);

  signal(SIGINT,SIG_IGN);

  // create CSV headers
  if (csvflag){
    if (interval){
      fprintf(outfile,"time,");
    }
    if (sflag) print_system(PRINT_CSV_HEADER);
    if (!interval && xflag) print_usage(NULL,PRINT_CSV_HEADER);
    print_metrics(cpu_info->systemwide_counters,PRINT_CSV_HEADER);
    fprintf(outfile,"\n");
  }

  // let the child start after two seconds
  sleep(2);

  if (sflag) read_system();

  clock_gettime(CLOCK_REALTIME,&start_time);
  if (launch_child(command_line_argc,command_line_argv,envp)){
    fatal("unable to launch %s\n",command_line_argv[0]);
  }

  if (interval){
    signal(SIGALRM,timer_callback);
    alarm(interval);
  }

  write(child_pipe[1],"start\n",6);
  if (treeflag){
    ptrace_setup(child_pid);
    fprintf(treefile,"0.000 %d root\n",child_pid);
    ptrace_loop();
    getrusage(RUSAGE_CHILDREN,&rusage);
  } else {
    // without ptrace, this process waits to complete
    wait4(child_pid,&status,0,&rusage);
  }

  is_still_running = 0;
  
  clock_gettime(CLOCK_REALTIME,&finish_time);

  read_system();

  // -----  
  // stop core-specific and system-wide counters
  for (i=0;i<cpu_info->num_cores;i++){
    if (cpu_info->coreinfo[i].core_specific_counters)
      read_counters(cpu_info->coreinfo[i].core_specific_counters,1);
  }
  read_counters(cpu_info->systemwide_counters,1);

  if (csvflag){
    if (interval){
      double elapsed;
  
      elapsed = finish_time.tv_sec + finish_time.tv_nsec / 1000000000.0 -
	start_time.tv_sec - start_time.tv_nsec / 1000000000.0;    
      fprintf(outfile,"%4.1f,",elapsed);
    }
    if (sflag) print_system(PRINT_CSV);
    if (xflag && !interval) print_usage(&rusage,PRINT_CSV);
    print_metrics(cpu_info->systemwide_counters,PRINT_CSV);    
    fprintf(outfile,"\n");    
  } else {
    if (sflag) print_system(PRINT_NORMAL);
    if (xflag) print_usage(&rusage,PRINT_NORMAL);
    print_metrics(cpu_info->systemwide_counters,PRINT_NORMAL);
  }

  for (i=0;i<cpu_info->num_cores;i++){
    if (cpu_info->coreinfo[i].core_specific_counters){
      if (csvflag){
	print_usage(&rusage,PRINT_CSV);
      } else {
	fprintf(outfile,"##### core %2d #######################\n",i);
      }
      print_metrics(cpu_info->coreinfo[i].core_specific_counters,csvflag?PRINT_CSV:PRINT_NORMAL);
      if (csvflag) fprintf(outfile,"\n");
    }
  }

  if (oflag) fclose(outfile);
  // -----

#if AMDGPU
  gpu_info_finalize();
#endif
  
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq 0xe5ac(%rip), %rax      # 0x11fc0
movq (%rax), %rax
movq %rax, 0xf6ea(%rip)      # 0x13108
callq 0x3350
movl %eax, 0xf6f3(%rip)      # 0x1311c
movl $0x2, %edi
callq 0x32a0
movl %eax, 0xf6e7(%rip)      # 0x13120
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x3470
cmpl $0x0, %eax
je 0x3a5f
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x9938(%rip), %rdi      # 0xd390
movb $0x0, %al
callq 0xbaf0
callq 0xb360
cmpl $0x0, %eax
je 0x3a77
leaq 0x9dcc(%rip), %rdi      # 0xd83c
movb $0x0, %al
callq 0xbaf0
callq 0x6500
callq 0x44d0
cmpl $0x0, 0xf650(%rip)      # 0x130d8
je 0x3b5f
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
leaq 0x106d1(%rip), %rcx     # 0x14170
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jae 0x3b5d
leaq 0x106be(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movb 0x4(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x3b4d
leaq 0x10698(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpl $0x2, (%rax)
je 0x3b2b
leaq 0x1067a(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpl $0x3, (%rax)
je 0x3b2b
leaq 0x1065c(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpl $0x6, (%rax)
jne 0x3b4d
leaq 0x1063e(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rdi
movslq -0x1c(%rbp), %rax
imulq $0x60, %rax, %rax
addq %rax, %rdi
addq $0x48, %rdi
callq 0x59f0
jmp 0x3b4f
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3a95
jmp 0x3b72
leaq 0x1060a(%rip), %rax     # 0x14170
movq (%rax), %rdi
addq $0x20, %rdi
callq 0x59f0
movl 0xe65c(%rip), %eax      # 0x121d4
andl $0x8000, %eax           # imm = 0x8000
cmpl $0x0, %eax
je 0x3bcb
leaq 0x96d7(%rip), %rdi      # 0xd260
callq 0x5370
movq %rax, -0xb8(%rbp)
cmpq $0x0, %rax
je 0x3bc9
leaq 0x105ce(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0xb8(%rbp), %rcx
leaq 0x105ae(%rip), %rax     # 0x14170
movq (%rax), %rax
movq %rcx, 0x20(%rax)
jmp 0x3bcb
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
leaq 0x10594(%rip), %rcx     # 0x14170
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jae 0x3c33
leaq 0x10585(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, 0x48(%rax)
je 0x3c26
leaq 0x10565(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rdi
callq 0x5dc0
jmp 0x3c28
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3bd2
leaq 0x10536(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
callq 0x5dc0
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
leaq 0x10519(%rip), %rcx     # 0x14170
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jae 0x3cae
leaq 0x1050a(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, 0x48(%rax)
je 0x3ca1
leaq 0x104ea(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rdi
callq 0x6100
jmp 0x3ca3
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3c4d
leaq 0x104bb(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
callq 0x6100
movl $0x2, %edi
movl $0x1, %esi
callq 0x31c0
cmpl $0x0, 0xf411(%rip)      # 0x130e8
je 0x3d57
cmpl $0x0, 0xf40c(%rip)      # 0x130ec
je 0x3cf7
movq 0xf41f(%rip), %rdi      # 0x13108
leaq 0xaf88(%rip), %rsi      # 0xec78
movb $0x0, %al
callq 0x31d0
cmpl $0x0, 0xf3e2(%rip)      # 0x130e0
je 0x3d0a
movl $0x2, %edi
callq 0xc8f0
cmpl $0x0, 0xf3db(%rip)      # 0x130ec
jne 0x3d2a
cmpl $0x0, 0xe4b6(%rip)      # 0x121d0
je 0x3d2a
xorl %eax, %eax
movl %eax, %edi
movl $0x2, %esi
callq 0x6570
leaq 0x1043f(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
movl $0x2, %esi
callq 0xaf90
movq 0xf3bf(%rip), %rdi      # 0x13108
leaq 0xb140(%rip), %rsi      # 0xee90
movb $0x0, %al
callq 0x31d0
movl $0x2, %edi
callq 0x3310
cmpl $0x0, 0xf378(%rip)      # 0x130e0
je 0x3d6f
callq 0xc3f0
xorl %edi, %edi
leaq 0x103e8(%rip), %rsi     # 0x14160
callq 0x3080
movl 0xf395(%rip), %edi      # 0x13118
movq 0xf386(%rip), %rsi      # 0x13110
movq -0x18(%rbp), %rdx
callq 0x4620
cmpl $0x0, %eax
je 0x3db0
movq 0xf371(%rip), %rax      # 0x13110
movq (%rax), %rsi
leaq 0x9ab4(%rip), %rdi      # 0xd85d
movb $0x0, %al
callq 0xbaf0
cmpl $0x0, 0xf335(%rip)      # 0x130ec
je 0x3dd5
movl $0xe, %edi
leaq 0x743b(%rip), %rsi      # 0xb200
callq 0x31c0
movl 0xf31c(%rip), %edi      # 0x130ec
callq 0x3140
leaq 0xf360(%rip), %rax      # 0x1313c
movl 0x4(%rax), %edi
leaq 0x9a8c(%rip), %rsi      # 0xd872
movl $0x6, %edx
callq 0x3090
cmpl $0x0, 0xf2f9(%rip)      # 0x130f0
je 0x3e3d
leaq 0xf338(%rip), %rax      # 0x13138
movl (%rax), %edi
callq 0x4800
movq 0xf2f2(%rip), %rdi      # 0x13100
leaq 0xf323(%rip), %rax      # 0x13138
movl (%rax), %edx
leaq 0x9a5b(%rip), %rsi      # 0xd879
movb $0x0, %al
callq 0x31d0
callq 0x49e0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq -0xb0(%rbp), %rsi
callq 0x3280
jmp 0x3e58
leaq 0xf2f4(%rip), %rax      # 0x13138
movl (%rax), %edi
leaq -0x20(%rbp), %rsi
xorl %edx, %edx
leaq -0xb0(%rbp), %rcx
callq 0x3250
leaq 0xf2e5(%rip), %rax      # 0x13144
movl $0x0, (%rax)
xorl %edi, %edi
leaq 0x102e2(%rip), %rsi     # 0x14150
callq 0x3080
callq 0xc3f0
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
leaq 0x102e7(%rip), %rcx     # 0x14170
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jae 0x3ee5
leaq 0x102d8(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, 0x48(%rax)
je 0x3ed8
leaq 0x102b8(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rdi
movl $0x1, %esi
callq 0x6250
jmp 0x3eda
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3e7f
leaq 0x10284(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
movl $0x1, %esi
callq 0x6250
cmpl $0x0, 0xf1e4(%rip)      # 0x130e8
je 0x3ff3
cmpl $0x0, 0xf1db(%rip)      # 0x130ec
je 0x3f8e
leaq 0x10236(%rip), %rax     # 0x14150
cvtsi2sdq (%rax), %xmm0
leaq 0x1022a(%rip), %rax     # 0x14150
cvtsi2sdq 0x8(%rax), %xmm1
movsd 0x92a4(%rip), %xmm2     # 0xd1d8
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
leaq 0x1021d(%rip), %rax     # 0x14160
cvtsi2sdq (%rax), %xmm1
subsd %xmm1, %xmm0
leaq 0x1020d(%rip), %rax     # 0x14160
cvtsi2sdq 0x8(%rax), %xmm1
movsd 0x9277(%rip), %xmm2     # 0xd1d8
divsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0xc0(%rbp)
movq 0xf190(%rip), %rdi      # 0x13108
movsd -0xc0(%rbp), %xmm0
leaq 0xb19a(%rip), %rsi      # 0xf121
movb $0x1, %al
callq 0x31d0
cmpl $0x0, 0xf14b(%rip)      # 0x130e0
je 0x3fa1
movl $0x1, %edi
callq 0xc8f0
cmpl $0x0, 0xe228(%rip)      # 0x121d0
je 0x3fc4
cmpl $0x0, 0xf13b(%rip)      # 0x130ec
jne 0x3fc4
leaq -0xb0(%rbp), %rdi
movl $0x1, %esi
callq 0x6570
leaq 0x101a5(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
movl $0x1, %esi
callq 0xaf90
movq 0xf125(%rip), %rdi      # 0x13108
leaq 0xaea6(%rip), %rsi      # 0xee90
movb $0x0, %al
callq 0x31d0
jmp 0x402f
cmpl $0x0, 0xf0e6(%rip)      # 0x130e0
je 0x4003
xorl %edi, %edi
callq 0xc8f0
cmpl $0x0, 0xe1c6(%rip)      # 0x121d0
je 0x401a
leaq -0xb0(%rbp), %rdi
xorl %esi, %esi
callq 0x6570
leaq 0x1014f(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x20(%rax), %rdi
xorl %esi, %esi
callq 0xaf90
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
leaq 0x10130(%rip), %rcx     # 0x14170
movq (%rcx), %rcx
cmpl 0xc(%rcx), %eax
jae 0x4109
leaq 0x1011d(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, 0x48(%rax)
je 0x40f9
cmpl $0x0, 0xf071(%rip)      # 0x130e8
je 0x408c
leaq -0xb0(%rbp), %rdi
movl $0x1, %esi
callq 0x6570
jmp 0x40a4
movq 0xf075(%rip), %rdi      # 0x13108
movl -0x1c(%rbp), %edx
leaq 0x97eb(%rip), %rsi      # 0xd888
movb $0x0, %al
callq 0x31d0
leaq 0x100c5(%rip), %rax     # 0x14170
movq (%rax), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x60, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rdi
movl 0xf021(%rip), %ecx      # 0x130e8
xorl %esi, %esi
movl $0x1, %eax
cmpl $0x0, %ecx
cmovnel %eax, %esi
callq 0xaf90
cmpl $0x0, 0xf008(%rip)      # 0x130e8
je 0x40f7
movq 0xf01f(%rip), %rdi      # 0x13108
leaq 0xada0(%rip), %rsi      # 0xee90
movb $0x0, %al
callq 0x31d0
jmp 0x40f9
jmp 0x40fb
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x4036
cmpl $0x0, 0xefcc(%rip)      # 0x130dc
je 0x411e
movq 0xefef(%rip), %rdi      # 0x13108
callq 0x30b0
xorl %eax, %eax
addq $0xc0, %rsp
popq %rbp
retq
nopl (%rax)