// File: /workspace/github_c_makefile_star2_O3/mvermeulen[P]wspy/topdown.c
// Function: read_counters
void read_counters(struct counter_group *counter_group_list,int stop_counters){
  int i,j;
  int status;
  struct counter_group *cgroup;
  
  struct read_format { uint64_t value, time_enabled, time_running,id; } rf;

  for (cgroup = counter_group_list;cgroup;cgroup = cgroup->next){
    debug("Stopping %s counters\n",cgroup->label);
    for (i=0;i<cgroup->ncounters;i++){
      if (cgroup->cinfo[i].fd != -1){
	status = read(cgroup->cinfo[i].fd,&rf,sizeof(rf));
	if (status == -1){
	  error("unable to read %s counter %s, errno=%d - %s\n",
		cgroup->label,cgroup->cinfo[i].label,errno,strerror(errno));
	} else {
	  cgroup->cinfo[i].prev_read = cgroup->cinfo[i].last_read;
	  cgroup->cinfo[i].last_read = rf.value;
	  // save only the delta since this was last read...
	  cgroup->cinfo[i].value = rf.value - cgroup->cinfo[i].prev_read;
	  cgroup->cinfo[i].time_running = rf.time_running;
	  cgroup->cinfo[i].time_enabled = rf.time_enabled;
	  // TODO: add scaling for performance counters...

	  if (stop_counters){
	    status = ioctl(cgroup->cinfo[i].fd,PERF_EVENT_IOC_DISABLE,0);
	  
	    if (status != 0){
	      error("unable to stop %s counter %s, errno=%d,%s\n",
		    cgroup->label,cgroup->cinfo[i].label,errno,strerror(errno));
	    } else {
	      debug("   stopped %s counter, name=%s, value=%lu enabled=%lu running=%lu\n",
		    cgroup->label,cgroup->cinfo[i].label,cgroup->cinfo[i].value,
		    rf.time_enabled,rf.time_running);
	    }
	  }
	}
      }
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %esi, 0x4(%rsp)
testq %rdi, %rdi
je 0x5535
movq %rdi, %r14
movq (%r14), %rsi
leaq 0x7759(%rip), %rdi      # 0xcb60
xorl %eax, %eax
callq 0x95da
cmpl $0x0, 0xc(%r14)
jle 0x5528
xorl %r12d, %r12d
xorl %r13d, %r13d
movq 0x18(%r14), %rax
movl 0x28(%rax,%r12), %edi
cmpl $-0x1, %edi
je 0x54f4
movl $0x20, %edx
leaq 0x8(%rsp), %rsi
callq 0x3160
cmpl $-0x1, %eax
jne 0x546d
movq (%r14), %rbx
movq 0x18(%r14), %rax
movq (%rax,%r12), %r15
callq 0x3040
movl (%rax), %ebp
movl %ebp, %edi
callq 0x32f0
leaq 0x7711(%rip), %rdi      # 0xcb76
movq %rbx, %rsi
movq %r15, %rdx
jmp 0x54e8
movq 0x18(%r14), %rax
movq 0x38(%rax,%r12), %rcx
movq %rcx, 0x40(%rax,%r12)
movq 0x8(%rsp), %rdx
movq %rdx, 0x38(%rax,%r12)
subq %rcx, %rdx
movq %rdx, 0x30(%rax,%r12)
movq 0x18(%rsp), %rbp
movq %rbp, 0x48(%rax,%r12)
movq 0x10(%rsp), %r15
movq %r15, 0x50(%rax,%r12)
cmpl $0x0, 0x4(%rsp)
je 0x54f4
movl 0x28(%rax,%r12), %edi
movl $0x2401, %esi           # imm = 0x2401
xorl %edx, %edx
xorl %eax, %eax
callq 0x3110
movq (%r14), %rsi
movq 0x18(%r14), %rcx
movq (%rcx,%r12), %rbx
testl %eax, %eax
je 0x550a
movq %rsi, %r15
callq 0x3040
movl (%rax), %ebp
movl %ebp, %edi
callq 0x32f0
leaq 0x76c1(%rip), %rdi      # 0xcba3
movq %r15, %rsi
movq %rbx, %rdx
movl %ebp, %ecx
movq %rax, %r8
xorl %eax, %eax
callq 0x9230
incq %r13
movslq 0xc(%r14), %rax
addq $0x58, %r12
cmpq %rax, %r13
jl 0x541f
jmp 0x5528
movq 0x30(%rcx,%r12), %rcx
leaq 0x76b8(%rip), %rdi      # 0xcbce
movq %rbx, %rdx
movq %r15, %r8
movq %rbp, %r9
xorl %eax, %eax
callq 0x95da
jmp 0x54f4
movq 0x20(%r14), %r14
testq %r14, %r14
jne 0x53fd
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq