/*our implements*/ void sema_up (struct semaphore *sema){ enum intr_level old_level; ASSERT (sema!=NULL); old_level=intr_disable(); sema->value ++ ; //DON'T MOVE IT:this one seems must been put here //if sema do have waiting threads if (!list_empty(&sema->waiters)) { /*unblock the thread with the highest priority*/ /*PRE:before we sema_up,we call the sema_down, which this will always gives you a sorted list of waiters , highest priority first*/ //thread with highest priority struct thread *max_t; struct list_elem *e = list_min(&sema->waiters, higher_priority, NULL); max_t = list_entry(e, struct thread, elem); //remove it from the waiter list list_remove(e); thread_unblock(max_t); } intr_set_level(old_level); }
/* Up or "V" operation on a semaphore. Increments SEMA's value and wakes up one thread of those waiting for SEMA, if any. This function may be called from an interrupt handler. */ void sema_up (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); old_level = intr_disable (); /* If the list of waiters isn't empty, retrieve and unblock the highest- priority waiter on the list. */ if (!list_empty (&sema->waiters)) { /* NOTE : The "highest priority" waiter will actually be the minimal list element, since priority_cmp is >, but list_min expects <. */ struct list_elem *highest_waiter = list_min (&sema->waiters, thread_priority_cmp, NULL); list_remove (highest_waiter); thread_unblock (list_entry (highest_waiter, struct thread, elem)); } sema->value++; intr_set_level (old_level); /* We may have just unblocked a thread with a higher priority than us, in which case we need to yield to it. */ thread_yield_to_max (); }
/* Up or "V" operation on a semaphore. Increments SEMA's value and wakes up one thread of those waiting for SEMA, if any. This function may be called from an interrupt handler. */ void sema_up (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); old_level = intr_disable (); sema->value++; if (!list_empty (&sema->waiters)) { /* Remove the highest priority thread from the waiting list and unblock Note: we use list_min because thread_priority_function is defined backwards */ struct list_elem *e = list_min (&sema->waiters, thread_priority_function, NULL); list_remove(e); struct thread* t = list_entry (e, struct thread, elem); thread_unblock (t); } intr_set_level (old_level); }
struct list_elem *rip_lowest(struct list *list, list_less_func *func, void *aux){ struct list_elem *e = list_min(list, func, aux); list_remove(e); return e; }