// File: /workspace/github_c_makefile_star2_O0/arkanis[P]process-map/map.c
// Function: UpdateTaskTraces
void UpdateTaskTraces(TaskTraces* traces, AddrRange ranges[], size_t rangeCount, size_t mapHilbertCurveOrder) {
	traces->currentTime++;
	// We use a hilbert curve order that can map each address to an x/y coordinate with byte accuracy (up from 4k per
	// pixel on the map). Because of that the addressOnMap below is calculated in bytes instead of 4k pages and the
	// calculated coordinates are later divided by 64 (side length of a 4k square).
	size_t byteAccurateHilberCurveOrder = mapHilbertCurveOrder + 6;
	
	for (size_t t = 0; t < traces->taskCount; t++) {
		if (traces->tasks[t].dead)
			continue;
		if ( ptrace(PTRACE_INTERRUPT, traces->tasks[t].pid, NULL, NULL) != 0 ) {
			traces->tasks[t].dead = true;
		  	perror("ptrace(PTRACE_INTERRUPT)");
		}
	}
	for (size_t t = 0; t < traces->taskCount; t++) {
		if (traces->tasks[t].dead)
			continue;
		Task* task = &traces->tasks[t];
		
		struct user_regs_struct regs;
		if ( waitpid(task->pid, NULL, 0) == -1 )                     perror("waitpid()");
		if ( ptrace(PTRACE_GETREGS, task->pid, NULL, &regs) != 0 )   perror("ptrace(PTRACE_GETREGS)");
		if ( ptrace(PTRACE_CONT, task->pid, NULL, NULL) != 0 )       perror("ptrace(PTRACE_CONT)");
		
		uint64_t addressOnMap = 0;
		for (size_t r = 0; r < rangeCount; r++) {
			if (regs.rip >= ranges[r].startAddr && regs.rip < ranges[r].endAddr) {
				addressOnMap = ranges[r].startPage * pageSize + (regs.rip - ranges[r].startAddr);
				break;
			}
		}
		
		int x, y;
		HilberCurveDistToPos(byteAccurateHilberCurveOrder, addressOnMap, &x, &y);
		TaskSample sample = (TaskSample){ .x = x / 64.0f, .y = y / 64.0f, .t = traces->currentTime };
		
		size_t currentParticleIndex = traces->currentTime % particleCount;
		glBindBuffer(GL_ARRAY_BUFFER, task->particleVBO);
			glBufferSubData(GL_ARRAY_BUFFER, currentParticleIndex * sizeof(TaskSample), sizeof(TaskSample), &sample);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x30(%rax)
movq -0x20(%rbp), %rax
addq $0x6, %rax
movq %rax, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x16616
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
testb $0x1, 0x1c(%rax)
je 0x165b4
jmp 0x16605
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl (%rax), %esi
movl $0x4207, %edi           # imm = 0x4207
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
movb $0x0, %al
callq 0x63b0
cmpq $0x0, %rax
je 0x16603
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movb $0x1, 0x1c(%rax)
leaq 0x75de9(%rip), %rdi     # 0x8c3e7
callq 0x6700
jmp 0x16605
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x1658c
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x16877
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
testb $0x1, 0x1c(%rax)
je 0x1664d
jmp 0x16866
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x6450
cmpl $-0x1, %eax
jne 0x16685
leaq 0x75d80(%rip), %rdi     # 0x8c400
callq 0x6700
movq -0x40(%rbp), %rax
movl (%rax), %esi
movl $0xc, %edi
xorl %eax, %eax
movl %eax, %edx
leaq -0x118(%rbp), %rcx
movb $0x0, %al
callq 0x63b0
cmpq $0x0, %rax
je 0x166b4
leaq 0x75d5b(%rip), %rdi     # 0x8c40a
callq 0x6700
movq -0x40(%rbp), %rax
movl (%rax), %esi
movl $0x7, %edi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
movb $0x0, %al
callq 0x63b0
cmpq $0x0, %rax
je 0x166df
leaq 0x75d47(%rip), %rdi     # 0x8c421
callq 0x6700
movq $0x0, -0x120(%rbp)
movq $0x0, -0x128(%rbp)
movq -0x128(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x1679e
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq $0xa0, -0x128(%rbp), %rdx
addq %rdx, %rcx
cmpq (%rcx), %rax
jb 0x16785
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq $0xa0, -0x128(%rbp), %rdx
addq %rdx, %rcx
cmpq 0x8(%rcx), %rax
jae 0x16785
movq -0x10(%rbp), %rax
imulq $0xa0, -0x128(%rbp), %rcx
addq %rcx, %rax
movq 0x30(%rax), %rax
shlq $0xc, %rax
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rdx
imulq $0xa0, -0x128(%rbp), %rsi
addq %rsi, %rdx
subq (%rdx), %rcx
addq %rcx, %rax
movq %rax, -0x120(%rbp)
jmp 0x1679e
jmp 0x16787
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0x166f5
movq -0x28(%rbp), %rdi
movq -0x120(%rbp), %rsi
leaq -0x12c(%rbp), %rdx
leaq -0x130(%rbp), %rcx
callq 0x16d60
cvtsi2ssl -0x12c(%rbp), %xmm0
movss 0x758b8(%rip), %xmm1    # 0x8c084
divss %xmm1, %xmm0
movss %xmm0, -0x13c(%rbp)
cvtsi2ssl -0x130(%rbp), %xmm0
movss 0x7589c(%rip), %xmm1    # 0x8c084
divss %xmm1, %xmm0
movss %xmm0, -0x138(%rbp)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, -0x134(%rbp)
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
movl $0x7d0, %ecx            # imm = 0x7D0
xorl %edx, %edx
divq %rcx
movq %rdx, -0x148(%rbp)
leaq 0xb5288(%rip), %rax     # 0xcbaa8
movq (%rax), %rax
movq -0x40(%rbp), %rcx
movl 0x18(%rcx), %esi
movl $0x8892, %edi           # imm = 0x8892
callq *%rax
leaq 0xb5278(%rip), %rax     # 0xcbab0
movq (%rax), %rax
imulq $0xc, -0x148(%rbp), %rsi
movl $0x8892, %edi           # imm = 0x8892
movl $0xc, %edx
leaq -0x13c(%rbp), %rcx
callq *%rax
movl $0x8892, %edi           # imm = 0x8892
xorl %esi, %esi
leaq 0xb5244(%rip), %rax     # 0xcbaa8
callq *(%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x1661e
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq