
길을 잃었다
void sema_up(struct semaphore *sema)
{
enum intr_level old_level;
ASSERT(sema != NULL);
old_level = intr_disable();
if (!list_empty(&sema->waiters))
{
list_sort(&sema->waiters, cmp_priority, 0);
thread_unblock(list_entry(list_pop_front(&sema->waiters), struct thread, elem));
}
sema->value++;
recheck_readyQueue();
intr_set_level(old_level);
}
void sema_down(struct semaphore *sema)
{
// sema -> 접근할 공유 자원의 개수?
enum intr_level old_level;
ASSERT(sema != NULL);
ASSERT(!intr_context());
old_level = intr_disable();
while (sema->value == 0)
{
// list_push_back(&sema->waiters, &thread_current()->elem);
// waiters 정렬 요구사항 구현위해 정렬하여 Push
list_insert_ordered(&sema->waiters, &thread_current()->elem, cmp_priority, NULL);
thread_block();
}
sema->value--;
intr_set_level(old_level);
}
void cond_wait(struct condition *cond, struct lock *lock)
{
struct semaphore_elem waiter;
ASSERT(cond != NULL);
ASSERT(lock != NULL);
ASSERT(!intr_context());
ASSERT(lock_held_by_current_thread(lock));
sema_init(&waiter.semaphore, 0);
// list_push_back(&cond->waiters, &waiter.elem);
list_insert_ordered(&cond->waiters, &waiter.elem, cmp_condval_priority, NULL);
lock_release(lock);
sema_down(&waiter.semaphore);
lock_acquire(lock);
}
리스트에 들어가는 원소 자료형이 semaphore_elem 자료형이다.
따라서 list_insert_ordered 함수에 들어가는 less 함수가 좀 달라야 한다.
우린 스레드의 우선순위를 가져와야 한다.
결국 자료형에 따라
semaphore_elem -> list -> thread 로 와야한다.
// 인자로 받는 Elem이 thread가 아닌 semaphore
bool cmp_condval_priority(struct list_elem *l, struct list_elem *s, void *aux UNUSED)
{
// thread까지 어떻게 접근?
struct semaphore_elem *l_semaphore = list_entry(l, struct semaphore_elem, elem);
struct semaphore_elem *s_semaphore = list_entry(s, struct semaphore_elem, elem);
struct list *l_semaphore_waiters = &(l_semaphore->semaphore.waiters);
struct list *s_semaphore_waiters = &(s_semaphore->semaphore.waiters);
struct thread *l_thread = list_entry(list_begin(l_semaphore_waiters), struct thread, elem);
struct thread *s_thread = list_entry(list_begin(s_semaphore_waiters), struct thread, elem);
return l_thread->priority > s_thread->priority;
}
void recheck_readyQueue()
{
int new_priority = thread_current()->priority;
struct thread *first_elem = list_entry(list_begin(&ready_list), struct thread, elem);
if (!list_empty(&ready_list) && first_elem->priority > new_priority)
{
thread_yield(); // 현재 CPU 점유중이던 스레드, CPU 자원 양보
}
}
ReadyQueue가 변동되는 경우가 많아서 따로 함수화 해주었다.

진짜 lock 부수고 싶다.