// File: /workspace/github_c_makefile_star2_O3/chrispanag[P]operating-systems-scheduler/scheduler.c
// Function: main
int main(int argc, char *argv[]) {
  int i;
  /*
  * For each of argv[1] to argv[argc - 1],
  * create a new child process, add it to the process list.
  */
  for (i = 0; i < argc - 1; i++) {
    pid_t pid = fork();
    if (pid < 0) {
      // Error code
      perror("fork");
    } else if (pid == 0) {
      // Child process code
      free(proc_list);  // Delete proc_list from child so that it doesn't have access to other processes

      char *executable = argv[i+1];
      char *newargv[] = { executable, NULL, NULL, NULL };
      char *newenviron[] = { NULL };
      raise(SIGSTOP);
      execve(executable, newargv, newenviron);
      // Unreachable point. Execve only returns on error.
      perror("execve");
      exit(1);
    } else {
      // Parent Code
      proc_list = addNode(proc_list, i, pid, argv[i+1]);
      nproc++;  /* number of proccesses goes here */
    }
  }

  if (nproc == 0) {
    fprintf(stderr, "Scheduler: No tasks. Exiting...\n");
    exit(1);
  }

  /* Wait for all children to raise SIGSTOP before exec()ing. */

  wait_for_ready_children(nproc);

  /* Install SIGALRM and SIGCHLD handlers. */
  install_signal_handlers();
  // Start the first process and set alarm
  kill(proc_list->pid, SIGCONT);
  alarm(SCHED_TQ_SEC);

  /* loop forever  until we exit from inside a signal handler. */
  //while (pause());
  while (1) {
    if (pause() == -1) {
      if (nproc == 0) {
        printf("No processes on the list. Exiting...\n");
        exit(0);
      }
    }
  }

  /* Unreachable */
  fprintf(stderr, "Internal error: Reached unreachable point\n");
  return 1;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
cmpl $0x2, %edi
jl 0x1647
movq %rsi, %rbx
movl %edi, %r14d
decl %r14d
xorl %r15d, %r15d
leaq 0xa34(%rip), %r12       # 0x2035
callq 0x1200
testl %eax, %eax
js 0x163d
movq 0x2b0f(%rip), %rdi      # 0x4120
je 0x16ee
movq 0x8(%rbx,%r15,8), %rcx
movl %r15d, %esi
movl %eax, %edx
callq 0x1488
movq %rax, 0x2af3(%rip)      # 0x4120
incl 0x2af5(%rip)            # 0x4128
incq %r15
cmpq %r15, %r14
jne 0x1601
jmp 0x1647
movq %r12, %rdi
callq 0x1190
jmp 0x1633
cmpl $0x0, 0x2ada(%rip)      # 0x4128
jne 0x1675
movq 0x29a1(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0x9e0(%rip), %rdi       # 0x2041
movl $0x20, %esi
movl $0x1, %edx
callq 0x11c0
jmp 0x1763
movl 0x2aad(%rip), %edi      # 0x4128
callq 0x1a9e
leaq 0x139(%rip), %rax       # 0x17c0
leaq 0x8(%rsp), %rbx
movq %rax, -0x8(%rbx)
movl $0x10000000, 0x80(%rbx) # imm = 0x10000000
leaq 0x98(%rsp), %r14
movq %r14, %rdi
callq 0x1120
movq %r14, %rdi
movl $0x11, %esi
callq 0x11f0
movq %r14, %rdi
movl $0xe, %esi
callq 0x11f0
movl $0x10, %ecx
movq %rbx, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rsp, %rsi
movl $0x11, %edi
xorl %edx, %edx
callq 0x1080
testl %eax, %eax
jns 0x173a
leaq 0x976(%rip), %rdi       # 0x2062
jmp 0x175e
callq 0x1050
movq 0x8(%rbx,%r15,8), %rbx
xorps %xmm0, %xmm0
movq %rsp, %r14
movaps %xmm0, (%r14)
movaps %xmm0, 0x10(%r14)
movq %rbx, (%r14)
leaq 0x98(%rsp), %r15
movq $0x0, (%r15)
movl $0x13, %edi
callq 0x1040
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x10f0
leaq 0x902(%rip), %rdi       # 0x203a
jmp 0x175e
leaq 0x253(%rip), %rax       # 0x1994
movq %rsp, %rsi
movq %rax, (%rsi)
movl $0xe, %edi
xorl %edx, %edx
callq 0x1080
testl %eax, %eax
jns 0x176d
leaq 0x917(%rip), %rdi       # 0x2075
callq 0x1190
movl $0x1, %edi
callq 0x11b0
movl $0x1, %esi
movl $0xd, %edi
callq 0x1100
movq 0x299d(%rip), %rax      # 0x4120
movl 0x4(%rax), %edi
movl $0x12, %esi
callq 0x1140
movl $0x2, %edi
callq 0x10e0
callq 0x1150
cmpl $-0x1, %eax
jne 0x179a
cmpl $0x0, 0x297d(%rip)      # 0x4128
jne 0x179a
leaq 0x915(%rip), %rdi       # 0x20c9
callq 0x1070
xorl %edi, %edi
callq 0x11b0