// File: /workspace/github_c_makefile_star2_O2/chrispanag[P]operating-systems-scheduler/scheduler.c
// Function: sigchld_handler
static void
sigchld_handler(int signum)
{
  // Create SIGSSET
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGALRM);
  
  // Disable SIGALRM
	if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
		perror("signals_disable: sigprocmask");
		exit(1);
	}

  int status;
  for (;;) {
    if (nproc <= 0) break; // If there are no child processes just exit.
    pid_t pid = waitpid(-1, &status, WUNTRACED | WNOHANG); // If one of the children has changed status return pid
    if (pid < 0) {
      perror("waitpid");
      exit(1);
    }
    if (pid == 0) break; // No children have stopped

    explain_wait_status(pid, status);

    if (WIFEXITED(status) || WIFSIGNALED(status)) {
      /* A child has died */
      node* stopped = accessNode(proc_list, pid);
      // Check if the child is the one running now
      if (stopped == proc_list) {
        kill(stopped->next->pid, SIGCONT);
        /* Reset Alarm */
        alarm(SCHED_TQ_SEC);
      }
      proc_list = deleteNode(proc_list, pid);
      nproc--;
      printf("Parent: Received SIGCHLD, child is dead. Exiting.\n");
    }
    if (WIFSTOPPED(status)) {
      /* A child has stopped due to SIGSTOP/SIGTSTP, etc... */
      printf("Parent: Child has been stopped. Moving right along...\n");
      node* stopped = accessNode(proc_list, pid);
      // Check if the child is the one running now
      if (stopped == proc_list) {
        kill(stopped->next->pid, SIGCONT);
        proc_list = proc_list->next;
        /* Reset Alarm */
        alarm(SCHED_TQ_SEC);
      }
    }
  }
  // Enable SIGALRM
  if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) {
		perror("signals_enable: sigprocmask");
		exit(1);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
leaq 0x8(%rsp), %rbx
movq %rbx, %rdi
callq 0x1120
pushq $0xe
popq %rsi
movq %rbx, %rdi
callq 0x11f0
xorl %edi, %edi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x1030
testl %eax, %eax
js 0x17a9
pushq $-0x1
popq %rbx
leaq 0x4(%rsp), %r14
pushq $0x3
popq %rbp
leaq 0xa91(%rip), %r13       # 0x20ee
leaq 0xabc(%rip), %r15       # 0x2120
cmpl $0x0, 0x2abd(%rip)      # 0x4128
jle 0x1770
movl %ebx, %edi
movq %r14, %rsi
movl %ebp, %edx
callq 0x1180
testl %eax, %eax
js 0x1795
je 0x1770
movl %eax, %r12d
movl 0x4(%rsp), %esi
movl %eax, %edi
callq 0x182a
movl 0x4(%rsp), %eax
movl %eax, %ecx
andl $0x7f, %ecx
je 0x16b5
shll $0x18, %ecx
addl $0x1000000, %ecx        # imm = 0x1000000
cmpl $0x2000000, %ecx        # imm = 0x2000000
jl 0x1712
movq 0x2a64(%rip), %rdi      # 0x4120
movl %r12d, %esi
callq 0x141b
movq 0x2a55(%rip), %rdi      # 0x4120
cmpq %rdi, %rax
jne 0x16ee
movq 0x10(%rax), %rax
movl 0x4(%rax), %edi
pushq $0x12
popq %rsi
callq 0x1140
pushq $0x2
popq %rdi
callq 0x10e0
movq 0x2a32(%rip), %rdi      # 0x4120
movl %r12d, %esi
callq 0x13d2
movq %rax, 0x2a23(%rip)      # 0x4120
decl 0x2a25(%rip)            # 0x4128
movq %r13, %rdi
callq 0x1070
movzbl 0x4(%rsp), %eax
jmp 0x1715
movzbl %al, %eax
cmpl $0x7f, %eax
jne 0x1664
movq %r15, %rdi
callq 0x1070
movq 0x29f3(%rip), %rdi      # 0x4120
movl %r12d, %esi
callq 0x141b
cmpq 0x29e4(%rip), %rax      # 0x4120
jne 0x1664
movq 0x10(%rax), %rax
movl 0x4(%rax), %edi
pushq $0x12
popq %rsi
callq 0x1140
movq 0x29c8(%rip), %rax      # 0x4120
movq 0x10(%rax), %rax
movq %rax, 0x29bd(%rip)      # 0x4120
pushq $0x2
popq %rdi
callq 0x10e0
jmp 0x1664
pushq $0x1
popq %rdi
leaq 0x8(%rsp), %rsi
xorl %edx, %edx
callq 0x1030
testl %eax, %eax
js 0x17b2
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x909(%rip), %rdi       # 0x20a5
callq 0x1190
pushq $0x1
popq %rdi
callq 0x11b0
leaq 0x8d8(%rip), %rdi       # 0x2088
jmp 0x179c
leaq 0x8f4(%rip), %rdi       # 0x20ad
jmp 0x179c