스핀락 코드를 잠깐 살펴봤는데 뮤텍스와 다르게 상당히 코드 복잡도가 낮습니다. tickets.next과 tickets.owner 두 값으로 스핀락을 획득하는 순서를 콘트롤하죠. spin_lock 함수가 처음 실행되는 시점에 tickets.owner 값을 로컬 변수에 저장하고 전역 tickets.next 값이 업데이트 될 때까지 Busy-wait합니다. 여기서 중요한 포인트는 tickets.owner 값을 로컬 변수 즉 스택 메모리 공간에 저장해서 제어한다는 점입니다. 모든 프로세스들은 각각 스택 공간에서 돌기 때문에 ticket 스핀락을 획득한 순서를 정확하게 파악할 수 있습니다.
낮은 복잡도에 정확하기 까지 합니다. 이렇게 스핀락 함수는 빠른 시간 내에 실행돼야 하는 인터럽트 서비스 루틴에서 공유 데이터를 보호하기 위해 씁니다.
스핀락 데드락이 생기면 어떻게 될 까요. 만약 어떤 프로세스가 스핀락을 획득하려고 하는데 이미 다른 모듈이 스핀락을 획득하고 해제하지 않으면 계속 while 루프 내에 돌면서 기다립니다. 이를 다른 말로 Busy-wait라고도 합니다. 그래서 어떤 프로세스가 스핀락을 획득하고 슬립에 빠지거나 무한 루프를 돌면 다른 프로세스들은 스핀락을 얻기 위해 계속 기다립니다. 대부분 시스템에서 이런 상황에서 결국 와치독 리셋으로 크래시가 발생합니다.
스핀락을 여러 방식으로 설명할 수 있는데 실제 소스 코드를 열어서 어셈블리 코드를 분석하는 게 가장 효율적으로 스핀락을 이해하는 길인 것 같습니다.
#Reference 시스템 콜
Reference(프로세스)
Reference(워크큐)
워크큐(Workqueue) Overview
최근 덧글