// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movl -0x14(%rbp), %eax
movl -0x8(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x1708
callq 0x11f0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0x163d
leaq 0xa02(%rip), %rdi       # 0x2035
callq 0x1190
jmp 0x16f8
cmpl $0x0, -0x18(%rbp)
jne 0x16bd
movq 0x2ace(%rip), %rdi      # 0x4118
callq 0x1050
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x10c0
movq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x10c0
movl $0x13, %edi
callq 0x1040
movq -0x20(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x48(%rbp), %rdx
callq 0x10e0
leaq 0x98c(%rip), %rdi       # 0x203a
callq 0x1190
movl $0x1, %edi
callq 0x11b0
movq 0x2a54(%rip), %rdi      # 0x4118
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rcx
callq 0x1360
movq %rax, 0x2a31(%rip)      # 0x4118
movl 0x2a33(%rip), %eax      # 0x4120
addl $0x1, %eax
movl %eax, 0x2a2a(%rip)      # 0x4120
jmp 0x16f8
jmp 0x16fa
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x160d
movl 0x2a12(%rip), %eax      # 0x4120
cmpl $0x0, %eax
jne 0x1735
movq 0x28de(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0x91d(%rip), %rsi       # 0x2041
movb $0x0, %al
callq 0x1100
movl $0x1, %edi
callq 0x11b0
movl 0x29e5(%rip), %edi      # 0x4120
callq 0x1d10
callq 0x17a0
movq 0x29cc(%rip), %rax      # 0x4118
movl 0x4(%rax), %edi
movl $0x12, %esi
callq 0x1140
movl $0x2, %edi
callq 0x10d0
callq 0x1150
cmpl $-0x1, %eax
jne 0x178f
movl 0x29ad(%rip), %eax      # 0x4120
cmpl $0x0, %eax
jne 0x178d
leaq 0x8e3(%rip), %rdi       # 0x2062
movb $0x0, %al
callq 0x10a0
xorl %edi, %edi
callq 0x11b0
jmp 0x178f
jmp 0x1763
nopw %cs:(%rax,%rax)