19.5.1.1. POSIX poll() 개념과 PX4 RTOS(NuttX) 환경에서의 추상화(px4_poll)
흔해 빠진 리눅스 데스크탑 C/C++ 개발 서버에서 TCP/UDP 소켓 통신(Socket)이나 무거운 비동기 파일 입출력(File I/O) 백엔드 코어를 한 번이라도 짜본 개발자라면 누구나 가슴속에 새겨둔 너무나 유명한 유닉스 POSIX 표준 시스템 콜(System Call)이 하나 있다. 바로 poll() 함수이다.
이 위대한 함수의 마법 같은 설계 철학은 “수신 서버 스레드를 미친 듯이 빙글빙글 도는 빈루프(Busy-waiting)로 태워 CPU를 혹사시키지 말고 완전히 기절시켜라. 대신, 내가 감시 카메라로 지정한 N개의 네트워크 소켓이나 파일 핸들 중, 단 하나라도 외부의 물리적 개입으로 인해 데이터가 들어와 ‘읽기 가능(Data Ready)’ 상태가 되면 OS 커널이 즉각 하드웨어 인터럽트를 걸어 가장 번개처럼 스레드를 깨워주겠다“는 것에 완벽한 뿌리를 두고 있다.
우리가 코딩하고 있는 PX4 펌웨어가 이식되어 구동되는 픽스호크 보드는 자원이 펑펑 남아도는 거대한 우분투 리눅스가 결코 아니며, 임베디드 코어 전용의 극한으로 메마른 초소형 실시간 운영체제(RTOS)인 NuttX 코어 커널 위에서 위태롭게 돌아간다.
하지만 위대한 PX4 코어 아키텍트들은 이 NuttX의 열악하고 척박한 보드 환경에서도, 수백 개의 텔레메트리 파일 시스템(VFS) 링 버퍼들을 유닉스의 poll()처럼 극도로 우아하고 반응성 높게 감시할 수 있도록, 이 표준 C API 기능을 커널단에서 완벽히 크로스 컴파일(Cross-compile) 래핑(Wrapping)하여 px4_poll 이라는 이름의 전처리 추상화 매크로로 창조해 내었다.
1. “Everything is a file“에 기반한 px4_poll의 VFS 렌더링 아키텍처
앞선 19.4 단원의 하드코어한 여정에서 우리가 건너편 미들웨어를 향해 orb_subscribe()를 냅다 타격하여 얻어냈던 최종 물리적 결과물이 무엇이었던가? 바로 고작 스레드 메모리에 떨어진 단순한 파일 디스크립터(File Descriptor), 텍스트 양수 핸들러 인덱스(int fd) 하나였다.
NuttX 운영체제의 관점에서 볼 때, 이 링 버퍼 fd는 단순히 SD카드 디스크에 정적으로 저장된 죽어있는 텍스트 파일이 절대 아니다. 저 건너편 스레드의 퍼블리셔가 데이터를 미친 듯이 코어에서 쓸어 담을 때마다 메모리 크기가 동적으로 늘어나며 상태가 1000Hz로 요동치는 ’살아 숨 쉬는 특수 인터럽트 읽기/쓰기 커널 노드 파이프’이다.
px4_poll 매크로는 이 파일 시스템 VFS 노드의 블로킹/논블로킹(Blocking/Non-blocking) 상태 기계(State Machine)를 커널 최심층부에서 모니터링한다. 우리가 퍼블리셔의 링 버퍼 fd를 구조체 배열에 정교하게 담아 px4_poll 시스템 콜에 통째로 던져 넣고 무한 루프 감방 문을 밖에서 걸어 잠그면, VFS 커널 스케줄러는 그 해당 fd 포인터 주소가 가리키는 실제 링 버퍼 꼬리단(Tail) 메모리를 고정 감시 카메라처럼 노려보게 된다.
2. 퍼블리셔의 타격(Publish)과 상태 점핑(Trigger Jumping) 인터럽트
감시가 이어지다 퍼블리셔 스레드 데몬이 드디어 메인 루프에서 orb_publish()를 실행하여 memcpy로 새로운 단 1바이트라도 데이터를 버퍼에 내려쓰는 폭력을 행사하는 바로 그 찰나의 순간, VFS 노드의 하드웨어 상태는 데이터 없음(Empty, Blocking)에서 **지금 당장 읽기 가능(POLLIN: Poll-In Event)**으로 트리거 점핑(Trigger Jumping)한다.
커널은 이 상태 퀀텀 점프(Jump) 이벤트를 L1 버스에서 포착하자마자 즉시 모든 우선순위를 무시하고 하드웨어 인터럽트를 날려, 블로킹 수면 큐(Wait Queue)에 처박혀 송장처럼 숨만 쉬고 있던 우리의 구독자 스레드의 멱살을 잡아채 강제 기상(Wake-up Signal)시켜 버리는 것이다.
이 추상화 래퍼 매크로의 존재 덕분에, 모듈 개발자는 수백 밀리초의 오차가 기체의 즉각적 자유 낙하 추락으로 이어지는 비행 제어 이너 루프의 극한의 실시간성(Real-time Constraints)을 커널단에서 완벽히 보장(Guarantee)받으면서도, 정작 픽스호크 CPU 코어 점유율은 데몬당 0.01% 바닥 레벨로 무자비하게 폭락시킬 수 있는 신의 권능 통제권을 쥐게 된 것이다.