// File: /workspace/github_c_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x120, %rsp            # imm = 0x120
cmpl $0x2, %edi
pushq $0x1
popq %r12
cmovgel %edi, %r12d
movq %rsi, %rbx
decl %r12d
xorl %r14d, %r14d
leaq 0xbc9(%rip), %r15       # 0x2035
cmpq %r14, %r12
je 0x14ae
callq 0x1200
testl %eax, %eax
js 0x14a4
movq 0x2c9f(%rip), %rdi      # 0x4120
je 0x14d8
movq 0x8(%rbx,%r14,8), %rcx
movl %r14d, %esi
movl %eax, %edx
callq 0x1346
movq %rax, 0x2c87(%rip)      # 0x4120
incl 0x2c89(%rip)            # 0x4128
incq %r14
jmp 0x146c
movq %r15, %rdi
callq 0x1190
jmp 0x149f
cmpl $0x0, 0x2c73(%rip)      # 0x4128
jne 0x1522
movq 0x2b3a(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0xb79(%rip), %rdi       # 0x2041
pushq $0x20
popq %rsi
pushq $0x1
popq %rdx
callq 0x11c0
jmp 0x15bb
callq 0x1050
movq 0x8(%rbx,%r14,8), %rbx
xorps %xmm0, %xmm0
movq %rsp, %r14
movaps %xmm0, (%r14)
movaps %xmm0, 0x10(%r14)
movq %rbx, (%r14)
leaq 0xa0(%rsp), %r15
andq $0x0, (%r15)
pushq $0x13
popq %rdi
callq 0x1040
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x10f0
leaq 0xb1d(%rip), %rdi       # 0x203a
jmp 0x15b6
movl 0x2c00(%rip), %edi      # 0x4128
callq 0x18fc
leaq 0xda(%rip), %rax        # 0x160e
leaq 0x8(%rsp), %rbx
movq %rax, -0x8(%rbx)
movl $0x10000000, 0x80(%rbx) # imm = 0x10000000
leaq 0xa0(%rsp), %r14
movq %r14, %rdi
callq 0x1120
pushq $0x11
popq %rbp
movq %r14, %rdi
movl %ebp, %esi
callq 0x11f0
pushq $0xe
popq %rsi
movq %r14, %rdi
callq 0x11f0
pushq $0x10
popq %rcx
movq %rbx, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rsp, %rsi
movl %ebp, %edi
xorl %edx, %edx
callq 0x1080
testl %eax, %eax
jns 0x1594
leaq 0xad0(%rip), %rdi       # 0x2062
jmp 0x15b6
leaq 0x220(%rip), %rax       # 0x17bb
movq %rsp, %rsi
movq %rax, (%rsi)
pushq $0xe
popq %rdi
xorl %edx, %edx
callq 0x1080
testl %eax, %eax
jns 0x15c3
leaq 0xabf(%rip), %rdi       # 0x2075
callq 0x1190
pushq $0x1
popq %rdi
callq 0x11b0
pushq $0xd
popq %rdi
pushq $0x1
popq %rsi
callq 0x1100
movq 0x2b4b(%rip), %rax      # 0x4120
movl 0x4(%rax), %edi
pushq $0x12
popq %rsi
callq 0x1140
pushq $0x2
popq %rdi
callq 0x10e0
callq 0x1150
cmpl $-0x1, %eax
jne 0x15e8
cmpl $0x0, 0x2b2f(%rip)      # 0x4128
jne 0x15e8
leaq 0xac7(%rip), %rdi       # 0x20c9
callq 0x1070
xorl %edi, %edi
callq 0x11b0