/*---------------------------------------------------------------------------*/
static void
call_process(struct process *p, process_event_t ev, process_data_t data)
{
  int ret;

#if DEBUG
  if(p->state == PROCESS_STATE_CALLED) {
    printf("process: process '%s' called again with event %d\n", PROCESS_NAME_STRING(p), ev);
  }
#endif /* DEBUG */
  
  if((p->state & PROCESS_STATE_RUNNING) &&
     p->thread != NULL) {
    PRINTF("process: calling process '%s' with event %d\n", PROCESS_NAME_STRING(p), ev);
    process_current = p;
    p->state = PROCESS_STATE_CALLED;
    ret = p->thread(&p->pt, ev, data);
    if(ret == PT_EXITED ||
       ret == PT_ENDED ||
       ev == PROCESS_EVENT_EXIT) {
      exit_process(p, p);
    } else {
      p->state = PROCESS_STATE_RUNNING;
    }
  }
}
Beispiel #2
0
void  _exit(int rc)
{
  if(current->proc->flags & PROC_FLAG_DEBUG)
  {
    debug("[info]EXIT(%x)\n", rc);
    print_areas(current->proc);
  }

  int i;
  process_t *p = current->proc;
  for(i = 0; i < NUM_FILEDES; i++)
  {
    if(p->fd[i])
    {
      close(i);
    }
  }

  exit_process(current->proc, rc);

  current->state = THREAD_STATE_FINISHED;

  schedule();

  debug("[error]ERROR! REACHED END OF EXIT SYSCALL!\n");
  for(;;);
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
static void call_process(struct process *p, process_event_t ev, process_data_t data)
{
  int ret;


  
  if((p->state & PROCESS_STATE_RUNNING) &&
     p->thread != 0) {
   
    process_current = p;
    p->state = PROCESS_STATE_CALLED;
    ret = p->thread(&p->pt, ev, data);
    if(ret == PT_EXITED ||
       ret == PT_ENDED ||
       ev == PROCESS_EVENT_EXIT) {
      exit_process(p, p);
    } else {
      p->state = PROCESS_STATE_RUNNING;
    }
  }
}
/*---------------------------------------------------------------------------*/
void
process_exit(struct process *p)
{
  exit_process(p, PROCESS_CURRENT());
}
Beispiel #5
0
void
interrupt(registers_t *reg)
{
	// The processor responds to a system call interrupt by saving some of
	// the application's state on the kernel's stack, then jumping to
	// kernel assembly code (in mpos-int.S, for your information).
	// That code saves more registers on the kernel's stack, then calls
	// interrupt().  The first thing we must do, then, is copy the saved
	// registers into the 'current' process descriptor.
	current->p_registers = *reg;

	switch (reg->reg_intno) {

	case INT_SYS_GETPID:
		// The 'sys_getpid' system call returns the current
		// process's process ID.  System calls return results to user
		// code by putting those results in a register.  Like Linux,
		// we use %eax for system call return values.  The code is
		// surprisingly simple:
		current->p_registers.reg_eax = current->p_pid;
		run(current);

	case INT_SYS_FORK:
		// The 'sys_fork' system call should create a new process.
		// You will have to complete the do_fork() function!
		current->p_registers.reg_eax = do_fork(current);
		run(current);

	case INT_SYS_YIELD:
		// The 'sys_yield' system call asks the kernel to schedule a
		// different process.  (MiniprocOS is cooperatively
		// scheduled, so we need a special system call to do this.)
		// The schedule() function picks another process and runs it.
		schedule();

	case INT_SYS_EXIT:
		// 'sys_exit' exits the current process, which is marked as
		// non-runnable.
		// The process stored its exit status in the %eax register
		// before calling the system call.  The %eax REGISTER has
		// changed by now, but we can read the APPLICATION's setting
		// for this register out of 'current->p_registers'.

		exit_process(current->p_pid);
		//current->p_state = P_ZOMBIE;
		//current->p_exit_status = current->p_registers.reg_eax;
		schedule();

	case INT_SYS_WAIT: {
		// 'sys_wait' is called to retrieve a process's exit status.
		// It's an error to call sys_wait for:
		// * A process ID that's out of range (<= 0 or >= NPROCS).
		// * The current process.
		// * A process that doesn't exist (p_state == P_EMPTY).
		// (In the Unix operating system, only process P's parent
		// can call sys_wait(P).  In MiniprocOS, we allow ANY
		// process to call sys_wait(P).)

		pid_t p = current->p_registers.reg_eax;
		if (p <= 0 || p >= NPROCS || p == current->p_pid // to check if ID is valid
		    || proc_array[p].p_state == P_EMPTY)
			current->p_registers.reg_eax = -1;
		else if (proc_array[p].p_state == P_ZOMBIE){ // to check if process already exited
			current->p_registers.reg_eax = proc_array[p].p_exit_status;
			proc_array[p].p_state = P_EMPTY; //sets the state to empty so that it can be reaped later
		} 
		else{
			// blocks the current process
			current->p_state = P_BLOCKED; 

			// waiting on proc_array[p]
			current->p_wait_on = p;
		}
			
		schedule();
		break;
	}

	
	// case INT_SYS_NEWTHREAD:
	// 	current->p_registers.reg_eax=do_newthread(current, current->p_registers.reg_ebx);
	// 	run(current);
	

	
	// case INT_SYS_KILL:
	// 	exit_process(current->p_registers.reg_ebx);
	// 	schedule();
	

	default:
		while (1)
			/* do nothing */;

	}
}
Beispiel #6
0
void sys_exit(){
	exit_process();
}