Пример #1
0
Файл: ipc.c Проект: tojonol/tos
//Sends data to specified port
void send (PORT dest_port, void* data)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS dest_process = dest_port->owner;
    //if (reciever is recieved blocked and port is open)
    if (dest_port->open && dest_process->state == STATE_RECEIVE_BLOCKED)
    {
        dest_process->param_proc = active_proc;
        dest_process->param_data = data;
        //Change Reciever to STATE_READY
        //taken care of by dispatch
        add_ready_queue (dest_process);
        //Change to STATE_REPLY_BLOCKED
        active_proc->state   = STATE_REPLY_BLOCKED;
    }
    //else
    else
    {
        active_proc->param_data = data;
        //Get on the send blocked list of the port
        if (dest_port->blocked_list_head == NULL)
            dest_port->blocked_list_head = active_proc;
        else
            dest_port->blocked_list_tail->next_blocked = active_proc;
        dest_port->blocked_list_tail = active_proc;
        active_proc->next_blocked = NULL;
        //change state to STATE_SEND_BLOCKED
        active_proc->state = STATE_SEND_BLOCKED;
    }
    active_proc->param_data = data;
    remove_ready_queue (active_proc);
    resign();
    ENABLE_INTR(flag);
}
Пример #2
0
void reply (PROCESS sender)
{
    if (sender->state != STATE_REPLY_BLOCKED)
	panic ("reply(): Not reply blocked");
    add_ready_queue (sender);
    resign();
}
Пример #3
0
Файл: ipc.c Проект: tojonol/tos
//Sends data to specified port
void message (PORT dest_port, void* data)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS dest_process = dest_port->owner;
    //if (receiver is receive blocked and port is open)
    if (dest_process->state == STATE_RECEIVE_BLOCKED && dest_port->open)
    {
        dest_process->param_proc  = active_proc;
        dest_process->param_data = data;
        //Change receiver to STATE_READY
        add_ready_queue (dest_process);
    }
    //else
    else
    {
        active_proc->param_data = data;
        //Get on the send blocked list of the port
        if (dest_port->blocked_list_head == NULL)
            dest_port->blocked_list_head = active_proc;
        else
            dest_port->blocked_list_tail->next_blocked = active_proc;
        dest_port->blocked_list_tail = active_proc;
        active_proc->next_blocked = NULL;
        remove_ready_queue (active_proc);
        //Change to STATE_MESSAGE_BLOCKED
        active_proc->state = STATE_MESSAGE_BLOCKED;
        active_proc->param_data = data;
    }
    resign();
    ENABLE_INTR(flag);
}
Пример #4
0
void send(PORT dest_port, void *data) {
  volatile unsigned int cpsr_flag;
  PROCESS dest;

  SAVE_CPSR_DIS_IRQ(cpsr_flag);
  assert(dest_port->magic == MAGIC_PORT);
  dest = dest_port->owner;
  assert(dest->magic == MAGIC_PCB);

  if (dest_port->open && dest->state == STATE_RECEIVE_BLOCKED) {
    /*
     * Receiver is receive blocked. We can deliver our message
     * immediately.
     */
    dest->param_proc = active_proc;
    dest->param_data = data;
    active_proc->state = STATE_REPLY_BLOCKED;
    //        kprintf("Wakeup %s, %s REPLY BLOCKED\n", dest->name,
    //        active_proc->name);
    add_ready_queue(dest);
  } else {
    /*
     * Receiver is busy or the port is closed.
     * Get on the send blocked queue of the port.
     */
    add_to_send_blocked_list(dest_port, active_proc);
    active_proc->state = STATE_SEND_BLOCKED;
    active_proc->param_data = data;
    //        kprintf("%s Send BLOCKED\n", active_proc->name);
  }
  active_proc->param_data = data;
  remove_ready_queue(active_proc);
  resign();
  RESUME_CPSR(cpsr_flag);
}
Пример #5
0
void message(PORT dest_port, void *data) {
  volatile unsigned int cpsr_flag;
  PROCESS dest;

  SAVE_CPSR_DIS_IRQ(cpsr_flag);
  assert(dest_port->magic == MAGIC_PORT);
  dest = dest_port->owner;
  assert(dest->magic == MAGIC_PCB);

  if (dest_port->open && dest->state == STATE_RECEIVE_BLOCKED) {
    dest->param_proc = active_proc;
    dest->param_data = data;
    add_ready_queue(dest);
    //        kprintf("Wakeup %s\n", dest->name);
  } else {
    /*
     * Receiver is busy or the port is closed.
     * Get on the send blocked queue of the port.
     */
    add_to_send_blocked_list(dest_port, active_proc);
    remove_ready_queue(active_proc);
    active_proc->state = STATE_MESSAGE_BLOCKED;
    active_proc->param_data = data;
    //        kprintf("%s Message BLOCKED\n", active_proc->name);
  }
  resign();
  RESUME_CPSR(cpsr_flag);
}
Пример #6
0
void send (PORT dest_port, void* data)
{
    PROCESS dest;

    assert (dest_port->magic == MAGIC_PORT);
    dest = dest_port->owner;
    assert (dest->magic == MAGIC_PCB);
    
    if (dest_port->open && dest->state == STATE_RECEIVE_BLOCKED) {
	/*
	 * Receiver is receive blocked. We can deliver our message
	 * immediately.
	 */
	dest->param_proc     = active_proc;
	dest->param_data     = data;
	active_proc->state   = STATE_REPLY_BLOCKED;
	add_ready_queue (dest);
    } else {
	/*
	 * Receiver is busy or the port is closed.
	 * Get on the send blocked queue of the port.
	 */
	add_to_send_blocked_list (dest_port, active_proc);
	active_proc->state = STATE_SEND_BLOCKED;
	active_proc->param_data = data;
    }
    active_proc->param_data = data;
    remove_ready_queue (active_proc);
    resign();
}
Пример #7
0
void reply(PROCESS sender) {
  volatile unsigned int cpsr_flag;
  SAVE_CPSR_DIS_IRQ(cpsr_flag);
  if (sender->state != STATE_REPLY_BLOCKED)
    panic("reply(): Not reply blocked");
  add_ready_queue(sender);
  //    kprintf("Wake up %s\n", sender->name);
  resign();
  RESUME_CPSR(cpsr_flag);
}
Пример #8
0
Файл: ipc.c Проект: tojonol/tos
void reply (PROCESS sender)
{
    volatile int flag;
    DISABLE_INTR (flag);
    //Add the process replied to back to the ready queue
    add_ready_queue (sender);
    //resign()
    resign();
    ENABLE_INTR (flag);
}
Пример #9
0
Файл: ipc.c Проект: tojonol/tos
void* receive (PROCESS* sender)
{
    volatile int flag;
    DISABLE_INTR(flag);
    PROCESS receiver_process;
    //Scanning send blocked list
    PORT p = active_proc->first_port;
    while (p != NULL) {
        if (p->open && p->blocked_list_head != NULL)
            // Found a process on the send blocked list
            break;
        p = p->next;
    }
    //if (send blocked list is not empty)
    if (p != NULL)
    {

        //sender = first process on the send blocked list
        receiver_process = p->blocked_list_head;
        *sender = receiver_process;

        //data = receiver_process->param_data;
        //cleanup pointer to next process
        p->blocked_list_head = p->blocked_list_head->next_blocked;
        if (p->blocked_list_head == NULL)
            p->blocked_list_tail = NULL;

        //if (sender is STATE_MESSAGE_BLOCKED)
        if (receiver_process->state == STATE_MESSAGE_BLOCKED)
        {
            //Change state of sender to STATE_READY
            add_ready_queue (receiver_process);
            ENABLE_INTR (flag);
            return receiver_process->param_data;
        }
        //if (sender is STATE_SEND_BLOCKED)
        else if (receiver_process->state == STATE_SEND_BLOCKED)
        {
            //Change state of sender to STATE_REPLY_BLOCKED
            receiver_process->state = STATE_REPLY_BLOCKED;
	          ENABLE_INTR (flag);
            return receiver_process->param_data;
        }
    }
    //else
    remove_ready_queue (active_proc);
    active_proc->param_data = NULL;
    active_proc->state = STATE_RECEIVE_BLOCKED;
    //Change to STATE_RECEIVED_BLOCKED
    resign();
    *sender = active_proc->param_proc;
    ENABLE_INTR (flag);
    return active_proc->param_data;
}
Пример #10
0
void *receive(PROCESS *sender) {
  PROCESS deliver_proc;
  PORT port;
  void *data;
  volatile unsigned int cpsr_flag;

  SAVE_CPSR_DIS_IRQ(cpsr_flag);
  data = NULL;
  port = active_proc->first_port;
  if (port == NULL)
    panic("receive(): no port created for this process");
  while (port != NULL) {
    assert(port->magic == MAGIC_PORT);
    if (port->open && port->blocked_list_head != NULL)
      break;
    port = port->next;
  }

  if (port != NULL) {
    deliver_proc = port->blocked_list_head;
    assert(deliver_proc->magic == MAGIC_PCB);
    *sender = deliver_proc;
    data = deliver_proc->param_data;
    port->blocked_list_head = port->blocked_list_head->next_blocked;
    if (port->blocked_list_head == NULL)
      port->blocked_list_tail = NULL;

    if (deliver_proc->state == STATE_MESSAGE_BLOCKED) {
      add_ready_queue(deliver_proc);
      //            kprintf("Receive wakeup %s\n", deliver_proc->name);
      RESUME_CPSR(cpsr_flag);
      return data;
    } else if (deliver_proc->state == STATE_SEND_BLOCKED) {
      deliver_proc->state = STATE_REPLY_BLOCKED;
      //            kprintf("%s reply blocked\n", deliver_proc->name);
      RESUME_CPSR(cpsr_flag);
      return data;
    }
  }

  /* No messages pending */
  active_proc->param_data = data;
  active_proc->state = STATE_RECEIVE_BLOCKED;
  //    kprintf("%s receive blocked\n", active_proc->name);
  remove_ready_queue(active_proc);
  resign();
  *sender = active_proc->param_proc;
  data = active_proc->param_data;
  RESUME_CPSR(cpsr_flag);
  return data;
}
Пример #11
0
void* receive (PROCESS* sender)
{
    PROCESS      deliver_proc;
    PORT         port;
    void         *data;

    data = NULL;
    port = active_proc->first_port;
    if (port == NULL)
	panic ("receive(): no port created for this process");
    while (port != NULL) {
	assert (port->magic == MAGIC_PORT);
	if (port->open && port->blocked_list_head != NULL)
	    break;
	port = port->next;
    }
    
    if (port != NULL) {
	deliver_proc = port->blocked_list_head;
	assert (deliver_proc->magic == MAGIC_PCB);
	*sender = deliver_proc;
	data = deliver_proc->param_data;
	port->blocked_list_head =
	    port->blocked_list_head->next_blocked;
	if (port->blocked_list_head == NULL)
	    port->blocked_list_tail = NULL;
	
	if (deliver_proc->state == STATE_MESSAGE_BLOCKED) {
	    add_ready_queue (deliver_proc);
	    return data;
	} else if (deliver_proc->state == STATE_SEND_BLOCKED) {
	    deliver_proc->state = STATE_REPLY_BLOCKED;
	    return data;
	}
    }

    /* No messages pending */
    remove_ready_queue (active_proc);
    active_proc->param_data = data;
    active_proc->state = STATE_RECEIVE_BLOCKED;
    resign();
    *sender = active_proc->param_proc;
    data = active_proc->param_data;
    return data;
}
Пример #12
0
void isr_timer(void) {
    PROCESS p = interrupt_table[TIMER_IRQ];
    if (p != NULL && p->state == STATE_INTR_BLOCKED) {
        // Add event handler to read queue
        add_ready_queue(p);
    }

    dmb(); // Memory barrier before/after write to peripheral
    get_system_timer()->CS.M3 = 1; // Clear system timer 3 interrupt
    /*
     * set up the new value in the C3 output compare register.  This is
     * done by reading the current low-order bits of the counter and adding the
     * requested number of cycles.  Note that wraparounds will necessarily be
     * handled correctly because the output compare registers are by design only
     * 32 bits.
     */
    get_system_timer()->C3 =
        get_system_timer()->CLO + (CLOCK_FREQ / CLKTICKS_PER_SEC);
    dmb();
}
Пример #13
0
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) {
    volatile int lock;
    DISABLE_INTR(lock);
    int i;
    for(i = 1; i < MAX_PROCS; i++) {
        if(pcb[i].used == FALSE) {
            pcb[i].magic = MAGIC_PCB;
            pcb[i].used = TRUE;
            pcb[i].priority = (unsigned short) prio;
            pcb[i].state = STATE_READY;
            pcb[i].esp = get_new_stack_frame(i, ptr_to_new_proc, param);
            pcb[i].first_port = create_new_port(&pcb[i]);
            pcb[i].name = name;

            add_ready_queue(&pcb[i]);
            ENABLE_INTR(lock);
            return pcb[i].first_port;
        }
    }
    ENABLE_INTR(lock);
    return (PORT) NULL;
}
Пример #14
0
//HOMEWORK 3
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM),
		     int prio,
		     PARAM param,
		     char *name)
{

    //initialize the process values
    LONG default_value = 0;
    MEM_ADDR     esp;
    PROCESS      new_proc;
    PORT         new_port;

    //HW7
    volatile int flag;//disable interrupts
    DISABLE_INTR(flag);

    new_proc = next_proc_ptr;
    next_proc_ptr = new_proc->next;

    //HW7
    ENABLE_INTR (flag);//reenable interrupts
    new_proc->magic             = MAGIC_PCB;
    new_proc->used              = TRUE;
    new_proc->state             = STATE_READY;
    new_proc->priority          = prio;
    new_proc->first_port        = NULL;
    new_proc->name              = name;

    new_port = create_new_port(new_proc);
    esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024;

    //PARAM
    esp = pushStack(esp, (LONG)param);
    //PROCESS
    esp = pushStack(esp, (LONG)new_proc);
    //RETURN ADDRESS
    esp = pushStack(esp, default_value);

    //Push interrupt flags if initialized
    //HW7 - slide 20 EFLAGS
    if (interrupts_initialized)
    {
	     esp = pushStack(esp, 512);
    }
    else
    {
	     esp = pushStack(esp, default_value);
    }
    //Push CodeSelector
    esp = pushStack(esp, CODE_SELECTOR);


    //ADDRESS OF NEW PROCESS
    esp = pushStack(esp, (LONG)ptr_to_new_proc);
    //EAX
    esp = pushStack(esp, default_value);
    //ECX
    esp = pushStack(esp, default_value);
    //EDX
    esp = pushStack(esp, default_value);
    //EBX
    esp = pushStack(esp, default_value);
    //EBP
    esp = pushStack(esp, default_value);
    //ESI
    esp = pushStack(esp, default_value);
    //EDI
    esp = pushStack(esp, default_value);
    new_proc->esp = esp;

    add_ready_queue (new_proc);
    return new_port;
}
Пример #15
0
void enable_keyboard() { add_ready_queue(keyb_notifier_proc); }
Пример #16
0
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM),
		     int prio,
		     PARAM param,
		     char *name)
{
   
   //For interrupts
   volatile int saved_if;
   DISABLE_INTR(saved_if);
   //end for interrupts

   //Look for empty
   int i;
   for(i = 0; i < MAX_PROCS; i++){
      if(pcb[i].used == FALSE)
         break;
   }

   MEM_ADDR esp;
   PROCESS new_proc = &pcb[i];
   
   new_proc->magic      = MAGIC_PCB;
   new_proc->used       = TRUE;
   new_proc->state      = STATE_READY;
   new_proc->priority   = prio;
   new_proc->first_port = NULL;
   new_proc->name       = name;

   PORT p = create_new_port(new_proc);

   esp = PROCESS_BASE - PROCESS_SIZE * i;
   
   poke_l(esp, param);
   esp -= sizeof(LONG);
   poke_l(esp, new_proc);
   esp -= sizeof(LONG);
   poke_l(esp, 0);
   esp -= sizeof(LONG);

   //For interrupts
   if(interrupts_initialized == TRUE)
      poke_l(esp, 512);
   else
      poke_l(esp, 0);
   esp -= sizeof(LONG);

   poke_l(esp, CODE_SELECTOR);
   esp -= sizeof(LONG);
   //End for interrupts

   poke_l(esp, ptr_to_new_proc);
   esp -= sizeof(LONG);
   
   //0 out register 
   poke_l(esp, 0);         //EAX
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //ECX
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //EDX
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //EBX
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //EBP
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //ESI
   esp -= sizeof(LONG);
   poke_l(esp, 0);         //EDI

   //Save the Stack pointer
   new_proc->esp = esp;

   add_ready_queue(new_proc);
   
   //For interrupts
   ENABLE_INTR(saved_if);
   //End for interrupts

   return p;
}
Пример #17
0
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM),
                     int prio,
                     PARAM param,
                     char *name)
{
    MEM_ADDR     esp;
    PROCESS      new_proc;
    PORT         new_port;
    volatile int flag;

    DISABLE_INTR (flag);
    if (prio >= MAX_READY_QUEUES)
        panic ("create(): Bad priority");
    if (next_free_pcb == NULL)
        panic ("create(): PCB full");
    new_proc = next_free_pcb;
    next_free_pcb = new_proc->next;
    ENABLE_INTR (flag);
    new_proc->used              = TRUE;
    new_proc->magic             = MAGIC_PCB;
    new_proc->state             = STATE_READY;
    new_proc->priority          = prio;
    new_proc->first_port        = NULL;
    new_proc->name              = name;

    new_port = create_new_port (new_proc);

    /* Compute linear address of new process' system stack */
    esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024;

#define PUSH(x)    esp -= 4; \
                   poke_l (esp, (LONG) x);

    /* Initialize the stack for the new process */
    PUSH (param);		/* First data */
    PUSH (new_proc);		/* Self */
    PUSH (0);			/* Dummy return address */
    if (interrupts_initialized) {
        PUSH (512);			/* Flags with enabled Interrupts */
    } else {
        PUSH (0);			/* Flags with disabled Interrupts */
    }
    PUSH (CODE_SELECTOR);	/* Kernel code selector */
    PUSH (ptr_to_new_proc);	/* Entry point of new process */
    PUSH (0);			/* EAX */
    PUSH (0);			/* ECX */
    PUSH (0);			/* EDX */
    PUSH (0);			/* EBX */
    PUSH (0);			/* EBP */
    PUSH (0);			/* ESI */
    PUSH (0);			/* EDI */

#undef PUSH

    /* Save context ptr (actually current stack pointer) */
    new_proc->esp = esp;

    add_ready_queue (new_proc);

    return new_port;
}