출발 상태: Poller-T는 epoll_wait() syscall로 커널의 wait queue에서 잠들어 있습니다. VT-1234는 어떤 소켓(fd=42)의 응답을 기다리며 park 상태로 힙에 보관됨. 캐리어는 idle.
핵심 메시지: 아무도 폴링하지 않습니다. 모두 잡니다. 시작 트리거는 NIC의 하드웨어 인터럽트. CPU가 강제로 Ring 0로 진입하고, 그 위에서 커널 코드(인터럽트 핸들러)가 실행되어 ① 패킷을 읽고 ② fd를 식별하고 ③ epoll ready list에 추가하고 ④ wake_up()으로 wait queue의 Poller를 ready queue로 옮깁니다.
큐 두 종류: wait queue는 자원별(epoll, mutex 등) — "이 자원 기다리며 잠든 쓰레드". ready queue는 CPU별 — "지금 CPU만 주면 뛸 쓰레드". 잠들 땐 ready→wait, 깨울 땐 wait→ready.
Java 차원의 다리: 커널은 fd만 알지 VT는 모름. fd → VT 매핑은 JDK가 Java 힙에 들고 있습니다. Poller가 깨어나서 epoll_wait() 결과(fd=42)를 받으면, 이 맵을 룩업해서 VT-1234를 찾고 LockSupport.unpark(VT-1234) 호출. 그러면 VT가 ForkJoinPool의 deque로 enqueue되고 한가한 캐리어가 mount.
행위자 구분: 하드웨어(NIC, CPU)는 신호 발사·명령어 실행만. 커널 코드가 큐 조작의 주체(wait↔ready). Java 코드가 fd→VT 변환과 ForkJoinPool 운영을 담당.