コード例 #1
0
ファイル: process.c プロジェクト: jsfr/OSM-Buenos
/**
 *
 * Terminate the current process (maybe).  If the current process has
 * more than one running thread, only terminate the current thread.
 * The process is only completely terminated (as per process_join
 * wakeup and page table deallocation) when the final thread calls
 * process_finish().
 *
 * @param The return value of the process.  This is only used when the
 * final thread exits.
 *
 */
void process_finish(int retval)
{
    interrupt_status_t intr_status;
    thread_table_t *thread = thread_get_current_thread_entry();
    process_id_t pid = thread->process_id;

    if (retval < 0) {
        /* Not permitted! */
        retval = 0;
    }

    intr_status = _interrupt_disable();
    spinlock_acquire(&process_table_slock);

    /* Mark the stack as free so new threads can reuse it. */
    process_free_stack(thread);

    if (--process_table[pid].threads == 0) {
        /* We are the last thread - kill process! */
        vm_destroy_pagetable(thread->pagetable);

        finish_given_process(pid, retval);
    }

    thread->pagetable = NULL;

    spinlock_release(&process_table_slock);
    _interrupt_set_state(intr_status);
    thread_finish();
}
コード例 #2
0
ファイル: process.c プロジェクト: Tayacan/OSM
void finish_given_process(process_id_t pid, int retval)
{
  process_id_t parent = process_table[pid].parent;
  process_id_t zombie;

  process_table[pid].retval = retval;

  while ((zombie = process_table[pid].first_zombie) >= 0) {
    /* We have zombie children - remove them. */
    process_table[zombie].state = PROCESS_FREE;
    process_table[zombie].retval = -1;
    process_table[zombie].parent = -1;
    process_table[pid].first_zombie = process_table[zombie].next_zombie;
    process_table[pid].children--;
  }

  if (parent >= 0
      && process_table[parent].state == PROCESS_ZOMBIE) {
    /* We have a zombie parent, implying we can never be
       joined. */
    if (--(process_table[parent].children) == 0
        && process_table[parent].retval < 0) {
      /* Oh, and our parent is joined and we are the last
         child. so free our parent. */
      finish_given_process(parent, 0);
    }
    process_table[pid].state = PROCESS_FREE;
  } else if (parent >= 0) {
    /* Our parent is alive and well, add us to its list of zombies */
    process_table[pid].state = PROCESS_ZOMBIE;
    zombie = process_table[parent].first_zombie;
    process_table[pid].next_zombie = zombie;
    if (zombie >= 0) {
      process_table[zombie].prev_zombie = pid;
    }
    process_table[parent].first_zombie = pid;
  } else {
    /* We have no parent, i.e. we are the initial program, and
       will be joined by the startup thread in init/main.c */
    process_table[pid].state = PROCESS_ZOMBIE;
  }

  sleepq_wake(&process_table[pid]);
}
コード例 #3
0
ファイル: process.c プロジェクト: Tayacan/OSM
/**
 *
 * Terminate the current process (maybe).  If the current process has
 * more than one running thread, only terminate the current thread.
 * The process is only completely terminated (as per process_join
 * wakeup and page table deallocation) when the final thread calls
 * process_finish().
 *
 * @param The return value of the process.  This is only used when the
 * final thread exits.
 *
 */
void process_finish(int retval)
{
  interrupt_status_t intr_status;
  thread_table_t *thread = thread_get_current_thread_entry();
  process_id_t pid = thread->process_id;

  if (retval < 0) {
    /* Not permitted! */
    retval = 0;
  }

  intr_status = _interrupt_disable();
  spinlock_acquire(&process_table_slock);

  vm_destroy_pagetable(thread->pagetable);

  finish_given_process(pid, retval);

  thread->pagetable = NULL;

  spinlock_release(&process_table_slock);
  _interrupt_set_state(intr_status);
  thread_finish();
}