struct Process *AllocProcess (void) { struct Process *proc; proc = LIST_HEAD (&free_process_list); KASSERT (proc != NULL); LIST_REM_HEAD (&free_process_list, free_entry); MemSet (proc, 0, sizeof *proc); proc->state = PROC_STATE_INIT; proc->exit_status = 0; proc->quanta_used = 0; proc->sched_policy = SCHED_OTHER; proc->tickets = STRIDE_DEFAULT_TICKETS; proc->stride = STRIDE1 / proc->tickets; proc->remaining = 0; proc->pass = global_pass; proc->vm_msg.state = VIRTUALALLOC_STATE_READY; // proc->continuation_function = NULL; // proc->virtualalloc_sz = 0; LIST_INIT (&proc->pending_handle_list); LIST_INIT (&proc->close_handle_list); free_process_cnt --; return proc; }
void CondBroadcast (struct Cond *cond) { struct Process *proc; if (current_process == NULL) return; do { DisableInterrupts(); proc = LIST_HEAD (&cond->blocked_list); if (proc != NULL) { LIST_REM_HEAD (&cond->blocked_list, blocked_entry); proc->state = PROC_STATE_READY; SchedReady (proc); Reschedule(); } proc = LIST_HEAD (&cond->blocked_list); EnableInterrupts(); } while (proc != NULL); }
void CondWait (struct Cond *cond, struct Mutex *mutex) { struct Process *proc; if (current_process == NULL) return; DisableInterrupts(); /* Release Mutex */ if (mutex->locked == TRUE) { proc = LIST_HEAD (&mutex->blocked_list); if (proc != NULL) { LIST_REM_HEAD (&mutex->blocked_list, blocked_entry); proc->state = PROC_STATE_READY; SchedReady (proc); } else { mutex->locked = FALSE; } } else { KPANIC ("CondWait() on a free mutex"); } /* Block current process on Condvar */ LIST_ADD_TAIL (&cond->blocked_list, current_process, blocked_entry); current_process->state = PROC_STATE_COND_BLOCKED; SchedUnready (current_process); Reschedule(); /* Now acquire mutex */ if (mutex->locked == TRUE) { LIST_ADD_TAIL (&mutex->blocked_list, current_process, blocked_entry); current_process->state = PROC_STATE_MUTEX_BLOCKED; SchedUnready (current_process); Reschedule(); } else { mutex->locked = TRUE; } EnableInterrupts(); }
int CreateAddressSpace (struct AddressSpace *as) { struct MemRegion *mr; KPRINTF ("CreateAddressSpace()"); MutexLock (&vm_mutex); if (PmapInit(as) == TRUE) { LIST_INIT (&as->sorted_memregion_list); LIST_INIT (&as->free_memregion_list); as->hint = NULL; as->page_cnt = 0; if ((mr = LIST_HEAD (&unused_memregion_list)) != NULL) { LIST_REM_HEAD (&unused_memregion_list, unused_entry); LIST_ADD_HEAD (&as->free_memregion_list, mr, free_entry); LIST_ADD_HEAD (&as->sorted_memregion_list, mr, sorted_entry); free_memregion_cnt --; LIST_INIT (&mr->pageframe_list); mr->as = as; mr->type = MR_TYPE_FREE; mr->prot = VM_PROT_NONE; mr->flags = MR_FLAGS_NONE; mr->base_addr = VM_USER_BASE; mr->ceiling_addr = VM_USER_CEILING; as->active = TRUE; MutexUnlock (&vm_mutex); return 0; } PmapDestroy(as); } as->active = FALSE; KPRINTF ("Failed to allocate address-space"); MutexUnlock (&vm_mutex); return -1; }
void Wakeup (struct Rendez *rendez) { struct Process *proc; DisablePreemption(); if ((proc = LIST_HEAD(&rendez->process_list)) == NULL) return; LIST_REM_HEAD (&rendez->process_list, rendez_link); proc->sleeping_on = NULL; proc->state = PROC_STATE_READY; SchedReady(proc); }
void CondTimedWaitCallout (struct Timer *timer, void *arg) { struct Process *proc; struct Cond *cond; cond = *(struct Cond **)arg; proc = timer->process; if (proc->state == PROC_STATE_COND_BLOCKED) { *(struct Cond **)arg = NULL; LIST_REM_HEAD (&cond->blocked_list, blocked_entry); proc->state = PROC_STATE_READY; SchedReady (proc); Reschedule(); } }
SYSCALL int AddInterruptHandler (int irq) { struct ISRHandler *isr_handler; struct Process *current; int handle; current = GetCurrentProcess(); if (!(current->flags & PROCF_ALLOW_IO)) return privilegeErr; if (free_handle_cnt < 1 || free_isr_handler_cnt < 1) return resourceErr; DisablePreemption(); handle = AllocHandle(); isr_handler = LIST_HEAD (&free_isr_handler_list); LIST_REM_HEAD (&free_isr_handler_list, isr_handler_entry); free_isr_handler_cnt --; isr_handler->irq = irq; isr_handler->handle = handle; SetObject (current, handle, HANDLE_TYPE_ISR, isr_handler); DisableInterrupts(); LIST_ADD_TAIL (&isr_handler_list[isr_handler->irq], isr_handler, isr_handler_entry); irq_handler_cnt[irq] ++; if (irq_handler_cnt[irq] == 1) UnmaskInterrupt(irq); EnableInterrupts(); return handle; }
void FreeAddressSpace (struct AddressSpace *as) { struct MemRegion *mr; struct Pageframe *pf; if (as->active == FALSE) return; MutexLock (&vm_mutex); while ((mr = LIST_HEAD (&as->sorted_memregion_list)) != NULL) { while ((pf = LIST_HEAD (&mr->pageframe_list)) != NULL) { LIST_REM_HEAD (&mr->pageframe_list, memregion_entry); pf->virtual_addr = 0; pf->state = PF_FREE; LIST_ADD_HEAD (&unused_pageframe_list, pf, unused_entry); free_pageframe_cnt ++; } LIST_REM_ENTRY (&as->sorted_memregion_list, mr, sorted_entry); LIST_ADD_HEAD (&unused_memregion_list, mr, unused_entry); free_memregion_cnt ++; } PmapDestroy (as); as->active = FALSE; MutexUnlock (&vm_mutex); }
int CondTimedWait (volatile struct Cond *cond, struct Mutex *mutex, struct TimeVal *tv) { struct Process *proc; struct Timer timer; if (current_process == NULL) return 0; DisableInterrupts(); if (mutex->locked == TRUE) { /* Release Mutex */ proc = LIST_HEAD (&mutex->blocked_list); if (proc != NULL) { LIST_REM_HEAD (&mutex->blocked_list, blocked_entry); proc->state = PROC_STATE_READY; SchedReady (proc); } else { mutex->locked = FALSE; } } else { KPANIC ("CondTimedWait() on a free mutex"); } /* Block current process on Condvar */ LIST_ADD_TAIL (&cond->blocked_list, current_process, blocked_entry); SetTimer (&timer, TIMER_TYPE_RELATIVE, tv, &CondTimedWaitCallout, &cond); current_process->state = PROC_STATE_COND_BLOCKED; SchedUnready (current_process); Reschedule(); CancelTimer (&timer); /* Now acquire mutex */ if (mutex->locked == TRUE) { LIST_ADD_TAIL (&mutex->blocked_list, current_process, blocked_entry); current_process->state = PROC_STATE_MUTEX_BLOCKED; SchedUnready (current_process); Reschedule(); } else { mutex->locked = TRUE; } EnableInterrupts(); if (cond == NULL) return -1; else return 0; }
int AllocDupAddressSpace (struct AddressSpace *src_as, struct AddressSpace *dst_as) { struct MemRegion *src_mr, *dst_mr; int error = 0; MutexLock (&vm_mutex); if (PmapInit (dst_as) == TRUE) { LIST_INIT (&dst_as->sorted_memregion_list); LIST_INIT (&dst_as->free_memregion_list); dst_as->hint = NULL; dst_as->page_cnt = src_as->page_cnt; src_mr = LIST_HEAD (¤t_process->user_as->sorted_memregion_list); while (src_mr != NULL && error == 0) { if ((dst_mr = LIST_HEAD (&unused_memregion_list)) != NULL) { LIST_REM_HEAD (&unused_memregion_list, unused_entry); LIST_ADD_TAIL (&dst_as->sorted_memregion_list, dst_mr, sorted_entry); free_memregion_cnt--; dst_mr->base_addr = src_mr->base_addr; dst_mr->ceiling_addr = src_mr->ceiling_addr; dst_mr->as = dst_as; dst_mr->type = src_mr->type; dst_mr->prot = src_mr->prot; dst_mr->flags = src_mr->flags; dst_mr->pageframe_hint = NULL; LIST_INIT (&dst_mr->pageframe_list); if (dst_mr->type == MR_TYPE_ANON) { if (AllocDupPageframes (dst_mr, src_mr) != 0) { error = -1; } } else if (dst_mr->type == MR_TYPE_FREE) { LIST_ADD_TAIL (&dst_as->free_memregion_list, dst_mr, free_entry); } } else { error = -1; } src_mr = LIST_NEXT (src_mr, sorted_entry); } } else { error = -1; } MutexUnlock (&vm_mutex); KASSERT (error != -1); return error; }