// File: /workspace/github_c_makefile_star2_O2/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)
movq %rdi, %r14
testq %r14, %r14
je 0x5484
movq (%r14), %rsi
leaq 0x67f6(%rip), %rdi      # 0xbb60
xorl %eax, %eax
callq 0x93c0
xorl %r13d, %r13d
xorl %r12d, %r12d
movslq 0xc(%r14), %rax
cmpq %rax, %r12
jge 0x547b
movq 0x18(%r14), %rax
movl 0x28(%rax,%r13), %edi
cmpl $-0x1, %edi
je 0x5451
leaq 0x8(%rsp), %rsi
pushq $0x20
popq %rdx
callq 0x3160
cmpl $-0x1, %eax
jne 0x53ca
movq (%r14), %rbx
movq 0x18(%r14), %rax
movq (%rax,%r13), %r15
callq 0x3040
movl (%rax), %ebp
movl %ebp, %edi
callq 0x3300
leaq 0x67ae(%rip), %rdi      # 0xbb76
jmp 0x543f
movq 0x18(%r14), %rax
movq 0x38(%rax,%r13), %rcx
movq %rcx, 0x40(%rax,%r13)
movq 0x8(%rsp), %rdx
movq %rdx, 0x38(%rax,%r13)
subq %rcx, %rdx
movq %rdx, 0x30(%rax,%r13)
movq 0x18(%rsp), %r15
movq %r15, 0x48(%rax,%r13)
movq 0x10(%rsp), %rbp
movq %rbp, 0x50(%rax,%r13)
cmpl $0x0, 0x4(%rsp)
je 0x5451
movl 0x28(%rax,%r13), %edi
movl $0x2401, %esi           # imm = 0x2401
xorl %edx, %edx
xorl %eax, %eax
callq 0x3110
movq (%r14), %rbx
movq 0x18(%r14), %rcx
movq (%rcx,%r13), %rdx
testl %eax, %eax
je 0x545d
movq %rdx, %r15
callq 0x3040
movl (%rax), %ebp
movl %ebp, %edi
callq 0x3300
leaq 0x6764(%rip), %rdi      # 0xbba3
movq %rbx, %rsi
movq %r15, %rdx
movl %ebp, %ecx
movq %rax, %r8
xorl %eax, %eax
callq 0x901e
incq %r12
addq $0x58, %r13
jmp 0x5377
movq 0x30(%rcx,%r13), %rcx
leaq 0x6765(%rip), %rdi      # 0xbbce
movq %rbx, %rsi
movq %rbp, %r8
movq %r15, %r9
xorl %eax, %eax
callq 0x93c0
jmp 0x5451
movq 0x20(%r14), %r14
jmp 0x5357
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq