/* * Disposes of the specified semaphore. */ ret_t ksema_free(struct ksema *sem) { unsigned long eflags; disable_hwint(eflags); if (!list_empty(sem->waiting_task_list_head)) { restore_hwint(eflags); return -E_BUSY; } kfree(sem); restore_hwint(eflags); return S_OK; }
void rs_putchar(char ch) { eflags_t eflags; disable_hwint(eflags); while (!is_transmit_empty()); out_byte(PORT, ch); restore_hwint(eflags); }
/* * Implements the DOWN operation on the specified kernel semaphore. * Do not call this function from an interrupt handler! */ void ksema_down(struct ksema *sem) { unsigned long eflags; disable_hwint(eflags); if (!sem->value) { /* Append the current task to the semaphore's wait queue and sleep. */ list_append(sem->waiting_task_list_head, current); current->state = TASK_UNINTERRUPTIBLE; schedule(); } /* Decrement the value of the semaphore. */ sem->value--; restore_hwint(eflags); }
/* * Implements the UP operation on the specified kernel semaphore. */ void ksema_up(struct ksema *sem) { unsigned long eflags; struct task_struct *t; disable_hwint(eflags); /* Increment the value of the semaphore. */ sem->value++; /* Remove the first task from the semaphore's wait queue and wake it up! */ if (!list_empty(sem->waiting_task_list_head)) { t = list_pop_head(sem->waiting_task_list_head); t->state = TASK_RUNNABLE; } restore_hwint(eflags); }