//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); }
void reply (PROCESS sender) { if (sender->state != STATE_REPLY_BLOCKED) panic ("reply(): Not reply blocked"); add_ready_queue (sender); resign(); }
//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); }
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); }
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); }
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(); }
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); }
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); }
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; }
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; }
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; }
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(); }
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; }
//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; }
void enable_keyboard() { add_ready_queue(keyb_notifier_proc); }
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; }
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; }