Interrupt Frame은 컴퓨터 시스템에서 인터럽트가 발생했을 때 현재 실행 중인 프로세스 또는 스레드의 상태를 보존하고 관리하는 데이터 구조입니다. 이 구조는 인터럽트가 처리되는 동안 중단된 작업을 재개하기 위해 필요한 정보를 저장합니다.
Interrupt Frame은 CPU 레지스터의 상태, 프로그램 카운터(PC), 스택 포인터(SP) 등의 중요한 정보를 포함합니다. 이 정보는 인터럽트 처리가 완료된 후에 현재 실행 중인 작업을 이어서 진행할 수 있도록 도와줍니다.
주요한 요소로는 다음과 같습니다:
CPU 레지스터 상태: Interrupt Frame에는 일반 목적 레지스터와 특수 목적 레지스터의 값이 저장됩니다. 이는 현재 실행 중인 작업의 레지스터 상태를 보존하는 데 사용됩니다.
프로그램 카운터 (PC): Interrupt Frame은 현재 실행 중인 명령어의 주소를 포함합니다. 인터럽트 처리가 완료된 후에는 이 주소로 다시 돌아가서 작업을 계속할 수 있습니다.
스택 포인터 (SP): Interrupt Frame은 현재 스택의 위치를 나타내는 스택 포인터 값을 포함합니다. 이를 통해 인터럽트 처리 중에도 스택에 대한 접근이 가능하며, 중단된 작업의 스택 상태를 유지할 수 있습니다.
Interrupt Frame은 인터럽트 처리를 위해 커널 내부에서 사용되며, 컨텍스트 스위칭과 관련된 작업에 중요한 역할을 합니다. 인터럽트가 발생하면 현재 실행 중인 작업의 상태를 저장하고, 인터럽트 처리가 완료된 후에는 저장된 상태를 복원하여 작업을 이어나갈 수 있도록 도와줍니다. 이를 통해 시스템은 다양한 이벤트와 인터럽트에 대응하며, 동시에 다중 작업을 지원할 수 있습니다.

✅ 05.25
✅ 05.26
✅ 05.27
✅ 05.28
✅ 05.29
✅ 05.30
✅ 05.31
synch.c - lock_acquire()
: donation list 저장방식의 차이

모든 waiters의 요소들을 donation list에 저장하기
void lock_acquire (struct lock *lock) {
ASSERT (lock != NULL);
ASSERT (!intr_context ());
ASSERT (!lock_held_by_current_thread (lock));
struct thread *curr = thread_current();
if (lock->holder != NULL) { // 이미 lock을 점유하고 있을 경우
curr->wait_on_lock = lock;
list_insert_ordered(&lock->holder->donations, &curr->donation_elem, donation_sort, NULL);
donate_priority(); // 우선순위 조정
}
sema_down (&lock->semaphore);
curr->wait_on_lock = NULL;
lock->holder = curr;
}

waiters의 최댓값만 donation list에 저장하기
void lock_acquire(struct lock *lock)
{
ASSERT(lock != NULL);
ASSERT(!intr_context());
ASSERT(!lock_held_by_current_thread(lock));
struct thread *curr = thread_current();
// if the lock is not available
if (lock->holder != NULL) {
curr->wait_on_lock = lock;
//lock을 잡고있는 스레드의 원래 우선순위보다 큰 경우
if (curr->priority > lock->holder->origin_priority) {
// waiters의 값이 처음 입력되는경우 = donation list에도 현재 lock에 대한 값이 없다.
if (list_empty(&lock->semaphore.waiters)) {
list_push_back(&lock->holder->donations, &curr->donation_elem); // add current thread into donation list.
}
//waiters에 값이 존재 = donation list에 현재 lock에 대한 값 존재
// 현재 스레드의 우선순위가 waiters의 가장 높은 우선순위보다 높으면 donation 안에 값을 바꿔줘야한다.
else if (list_entry(list_front(&lock->semaphore.waiters), struct thread, elem)->priority < curr->priority) {
struct list_elem *e;
//donation list를 탐색
for (e = list_begin(&lock->holder->donations); e != list_end(&lock->holder->donations); e = list_next(e)) {
struct thread *t = list_entry(e, struct thread, donation_elem);
// 받아온 락이 wait_on_lock일경우
if (lock == t->wait_on_lock && &t->donation_elem != NULL) {
list_remove(&t->donation_elem);
// insert current thread in the donation list before the thread with lower priority
list_insert_ordered(&t->donations, &curr->donation_elem, donation_sort, NULL);
break;
}
else{
list_insert_ordered(&t->donations, &curr->donation_elem, donation_sort, NULL);
break;
}
}
}
donate_priority();
}
}
sema_down(&lock->semaphore);
lock->holder = curr;
curr->wait_on_lock = NULL;
}
커널 연결리스트의 구조

list_remove(find(&lock->holder->donations, list_head(&lock->semaphore.waiters)));
list_remove(&t->donation_elem);
🗒️ 이번 주차 후기
코드를 짜는데 있어서 너무 많은 것을 한번에 생각하면서 비효율적인 일주일을 보낸 것같다.
순서대로 하나씩 했더라면 훨씬 효율적이었을 것 같았다. 다음 주차에는 개념정리를 좀 더 확실하게 하여 구현 순서를 이해하면서 코드를 짤 수 있도록 해야겠다.
지금 당장 무엇을 해야하는지를 아는 것이 가장 중요하다고 느껴진 주차였다.
또한 다음주차에는 기록을 좀 더 해두어야 겠다.