18.5.3. 데이터 페치(`orb_copy`) 시점의 Tearing 현상 방지 알고리즘

18.5.3. 데이터 페치(orb_copy) 시점의 Tearing 현상 방지 알고리즘

PX4-Autopilot의 실시간 운영체제 환경에서 다수의 발행자(Publisher)와 구독자(Subscriber)가 단일 토픽(Topic) 버퍼를 두고 비동기적으로(Asynchronously) 통신할 때, 가장 경계해야 하는 메모리 오염 문제가 바로 ‘티어링(Tearing)’ 현상이다. 본 절에서는 구독자가 orb_copy API를 통해 데이터를 페치(Fetch)해 올 때, 무거운 뮤텍스 락(Mutex Lock) 없이 어떻게 티어링 결함을 원천 차단하는지 그 핵심 알고리즘 구조를 심층적으로 분석한다.

1. 데이터 티어링(Tearing) 현상의 이해

티어링 현상이란 독자(Reader)가 메모리를 읽어오는 물리적 시간 도중에, 필드 중 일부 데이터 구조체가 찢어지듯 갱신(Update)되어 논리적으로 훼손된 무결성 불량 데이터를 취득하게 되는 현상을 뜻한다.

  • 발생 시나리오: mc_pos_control (멀티로터 위치 제어기) 프로세스가 vehicle_local_position 버퍼 배열의 앞쪽 바이트를 읽고 있는 찰나에, 상대적으로 높은 컨텍스트 우선순위를 지닌 EKF2 상태 추정기 스레드가 선점(Preemption) 권한을 발동하여 버퍼 전체를 완전히 새로운 값으로 덮어쓸 경우가 대표적이다.
  • 결과: 제어기는 절반은 과거 주기의 위치 데이터, 나머지 절반은 방금 도착한 미래 주기의 편향 데이터가 뒤섞인 치명적인 ’프랑켄슈타인 데이터’를 진실로 믿고 모터 제어 명령을 산출하게 되며, 이는 드론의 예측 불가능한 역학적 장열(Crash)이나 물리적 추락으로 직결될 수 있다.

2. 락프리 기반의 Generation Counter 이중 확인(Double-Check) 알고리즘

전통적인 POSIX 프로그래밍에서는 읽기/쓰기 락(Read/Write Lock) 버스나 세마포어(Semaphore) 블로킹을 통해 티어링을 방어하지만, PX4는 하드 리얼타임(Hard Real-time)의 무자비한 응답 요구 조건을 관철하기 위해 세대 카운터(generation)를 응용한 락프리 이중 확인(Lock-free Double-check) 접근법을 고안해 냈다.

orb_copy 함수 내부 버퍼 접근 로직은 근본적으로 다음과 같은 순서의 파이프라인으로 구성된다.

// uORB 데이터 락프리 페치(orb_copy) 과정 시뮬레이션 코드 (개념적 표현)

bool copy_successful = false;
while (!copy_successful) {
    // 1. 읽기 시작 전: 현재 노드의 전역 카운터 스냅샷 촬영
    unsigned gen_before = node->global_generation;
    
    // 2. 물리적인 메모리 복사 수행 (memcpy)
    memcpy(subscriber_buffer, node->buffer, data_size);
    
    // 3. 읽기 종료 후: 다시 노드의 전역 카운터 스냅샷 촬영
    unsigned gen_after = node->global_generation;
    
    // 4. 무결성 검증 (Tearing 방어)
    if (gen_before == gen_after) {
        // 복사 도중 발행자의 간섭(Overwrite)이 전혀 없었음 -> 완전한 한 덩어리 복사 성공
        subscriber->local_generation = gen_after; 
        copy_successful = true;
    } else {
        // 복사 도중 데이터가 덮어씌워짐 (Tearing 파괴 발생) -> 결함 데이터 폐기 후 재시도(Retry)
        continue;
    }
}

이 C++ 로직은 메모리 장벽(Memory Barrier) 메커니즘을 극대화한 방식으로, 메모리 복사에 소요된 나노초 단위의 짧은 시간 동안에 발행자의 침범이 있었는지를 memcpy() 시작 전과 끝난 후의 무부호 카운터 일치 여부 단 하나만으로 명백히 확정 지을 수 있다.

3. Tearing 방어 동기화의 시스템적 파급 효과

PX4가 채택한 해당 알고리즘은 타 운영체제 미들웨어와 비교할 때 강력한 병렬 처리(Concurrency) 효율을 스스로 입증한다.

  1. 독립성의 극대화: orb_copy를 실행하는 구독 태스크는 절대 휴면(Sleep) 상태로 강제 블로킹되지 않는다. 무결성이 확보될 때까지 단순히 루프를 초고속으로 다시 실행할 뿐이므로, 다른 큐 시스템의 흐름에 악영향을 파급시키지 않는다.
  2. 스핀락(Spinlock) 구조 대비 자원 절약: 무한 루프처럼 보이나, 단일 토픽 최대 갱신 주기(예: 1kHz = 1ms) 대비 memcpy 소요 시간(보통 수백 ns 이내)이 압도적으로 짧기 때문에 재시도 충돌 횟수는 통상적으로 0~1회 단위에 근접하며, 선형적인 락 대기 오버헤드 비용 곡선을 비약적으로 떨어뜨린다.
  3. 결정론적(Deterministic) 실시간성 부여: 최악의 분산 시나리오에서도 상호 배제 경합(Lock Contention)에 의한 예측 불가능한 데드라인(Deadline) 초과 위험을 거세함으로써 비행 제어 루프의 실행 지연 시간을 항상 예측 가능한 수학적 상수로 옹위한다.

결론적으로 uORB의 orb_copy 티어링 방지 검증 알고리즘은 멀티 코어 MCU나 고속 코프로세서(Coprocessor) 환경을 막론하고 데이터 버퍼의 시간적·공간적 일관성을 완벽히 조율해 주는 PX4-Autopilot 아키텍처의 필수 방호벽이다.