Skip to the content.

WFE 명령어 (Wait For Event)

Summary

정의: 프로세서를 저전력 대기 상태로 진입시키는 명령어. 특정 이벤트(Event) 가 발생할 때까지 실행을 중단하고 대기함. 이벤트 발생 시 자동으로 깨어나 다음 명령어부터 실행 재개함.


문법

WFE

특징: 오퍼랜드가 없는 단독 명령어임.


질문에 대한 직접 답변 — “일반적으로 사용 가능한가?”

결론: EL0(일반 사용자 애플리케이션)에서도 실행 가능함. 이전에 다룬 AT(특권 명령어)와는 다르게, WFE는 특권 레벨 제약이 없는 일반 명령어임.

단, 실제 사용 빈도는 매우 제한적: 일반 애플리케이션 코드(예: 단순 로직, 계산, 문자열 처리)에서는 거의 등장하지 않고, 저수준 동기화 프리미티브(스핀락, 뮤텍스)를 직접 구현하는 라이브러리 코드커널의 유휴(idle) 루프에서 주로 관찰됨.


동작 원리

대기 해제(wake-up) 조건:

  1. 이벤트 레지스터(Event Register) 설정 — 다른 코어가 SEV(Send Event) 명령어를 실행한 경우
  2. 배타적 모니터 클리어 — 이전에 다룬 LDXR로 설정한 배타적 모니터가 다른 코어의 접근으로 클리어된 경우 (자동으로 이벤트 발생)
  3. 인터럽트 발생 — IRQ, FIQ 등 예외 상황
  4. 디버그 이벤트

중요한 안전장치: WFE는 “이벤트가 절대 안 오면 영원히 멈춘다”는 위험이 없도록 설계됨. 위 조건 중 하나라도 만족하면 즉시 깨어나며, 심지어 아무 이유 없이도 스퓨리어스(spurious)하게 깨어날 수 있음 — 그래서 항상 루프 안에서 조건을 재확인하는 패턴으로 사용해야 함.


WFE와 짝을 이루는 명령어 — SEV (Send Event)

정의: 다른 모든 코어에 이벤트를 broadcast하여 WFE로 대기 중인 코어를 깨우는 명령어.

SEV

전형적 사용 패턴:

코어 A: WFE (대기)
코어 B: 공유 자원 해제 후 → SEV (코어 A 깨움)
코어 A: 이벤트 수신 → 깨어나서 조건 재확인

실전 활용 — 스핀락 최적화 패턴

단순 스핀락의 문제점: 락이 풀리기를 기다리며 무한 루프를 도는 경우, CPU 자원과 전력을 낭비함.

// 비효율적인 순수 스핀락 (전력 낭비)
spin_loop:
    ldxr w0, [x1]              // 락 상태 로드
    cbnz w0, spin_loop           // 락이 걸려있으면 계속 반복 (busy-wait)

WFE를 활용한 최적화된 스핀락:

spin_loop:
    ldaxr w0, [x1]             // 락 상태 로드 (배타적 모니터 설정)
    cbz   w0, try_lock           // 락이 풀려있으면 획득 시도
    wfe                            // 락이 걸려있으면 저전력 대기
    b     spin_loop                // 깨어나면 다시 확인

try_lock:
    mov w2, #1
    stxr w3, w2, [x1]             // 락 획득 시도
    cbnz w3, spin_loop              // 실패 시 재시도
    // 락 획득 성공

핵심 이점: LDXR로 설정된 배타적 모니터는 다른 코어가 해당 주소에 쓰기(락 해제)를 하면 자동으로 클리어되고, 이것이 곧 WFE의 wake-up 이벤트로 작동함. 즉 별도의 SEV 호출 없이도 락 해제 시 자동으로 대기 코어가 깨어남 (배타적 모니터 메커니즘과 이벤트 메커니즘이 연동되어 있음).


커널 유휴(Idle) 루프에서의 활용

용도: 운영체제 커널이 실행할 작업이 없을 때, CPU를 완전히 멈추지 않고 저전력 대기 상태로 전환하여 배터리 소모를 줄이는 데 사용됨.

idle_loop:
    wfe                    // 인터럽트나 이벤트가 올 때까지 저전력 대기
    // 인터럽트 처리 후 여기로 복귀
    b idle_loop

macOS/iOS 맥락: XNU 커널의 유휴 루프, 또는 Grand Central Dispatch(GCD)의 저수준 스레드 대기 구현 등에서 이런 패턴이 활용될 수 있음 (다만 실제 커널 소스 세부사항은 공개 범위가 제한적임).


WFE vs WFI — 유사 명령어 비교

명령어 정식 명칭 깨우는 조건
WFE Wait For Event 이벤트(SEV, 배타적 모니터 클리어, 인터럽트 등)
WFI Wait For Interrupt 인터럽트만 (더 제한적)

차이: WFE는 이벤트 메커니즘(소프트웨어적으로 SEV로도 트리거 가능)까지 포함하는 더 넓은 대기 조건을 가지며, WFI는 순수하게 하드웨어 인터럽트만을 기다림. 스핀락 같은 코어 간 소프트웨어 동기화에는 WFE가, 단순 유휴 대기에는 WFI가 더 적합한 경우가 많음.


결론적 정리

항목 내용
특권 레벨 EL0(일반)에서도 실행 가능
일반 앱에서 관찰 빈도 낮음 (직접 작성하는 경우 드묾)
실제 등장 맥락 스핀락 구현, 저수준 동기화 라이브러리, 커널 유휴 루프
짝 명령어 SEV (이벤트 발생시켜 깨움)
관련 명령어 WFI(인터럽트 전용 대기)

최종 판단: 문법적으로는 “일반적으로 사용 가능”하지만, 실질적으로는 락-프리 동기화 프리미티브나 시스템 저수준 코드를 직접 작성하는 경우가 아니라면 애플리케이션 개발자가 직접 손으로 작성할 일은 거의 없는 명령어임. 다만 pthread_mutex, os_unfair_lock 같은 macOS 동기화 API의 내부 구현을 리버싱하다 보면 마주칠 가능성이 있는 명령어임.