2009-12-28 5 views
4

나는 (S [O | F | U] 네트워크와 다른 곳에서) 열심히 수색했으며, 드문 질문이라고 생각합니다. Debian Linux 2.6.28-4를 실행하는 Atmel AT91SAM9263-EK 개발 보드 (ARM926EJ-S 코어, ARMv5 명령어 세트)로 작업하고 있습니다. 나는와 이야기하기 위해 tty 드라이버를 사용하여 (나는) 내가 쓰고있다. 쓰기와 읽기가 원자적임을 확실히해야합니다. 커널 소스 설치 디렉토리와 관련하여이 게시물의 끝 아래에 나열된 몇 줄의 소스 코드는이를 암시하거나 암묵적으로 설명합니다.원자 기록을 확인하는 방법?

이 장치에서 쓰거나 읽는 것이 실제로 원자 적 작업인지 확인할 수있는 방법이 있습니까? 또는/dev/ttyXX 장치가 FIFO로 간주되고 인수가 거기에서 종료됩니까? 코드가이 주장을 시행하고 있다는 것을 단순히 믿는 것만으로는 충분하지 않습니다 - 최근 2 월의 freebsd는 demonstrated to lack atomic writes for small lines이었습니다. 그렇습니다. FreeBSD는 Linux와 완전히 똑같지는 않지만, 요점은 신중해야한다는 것입니다. 제가 생각할 수있는 것은 데이터를 계속 보내고 순열을 찾는 것입니다. 저는 좀 더 과학적이고 이상적으로 결정론적인 것을 기대하고있었습니다. 불행히도, 나는 요즘 대학 시절의 동시 프로그래밍 수업에서 정확히 아무것도 기억하지 못합니다. 나는 철저히 올바른 방향으로 때 리거나 쑤셔 주셔서 감사합니다. 답장을 보내 주시면 미리 감사드립니다.

종류와 관련,

Jayce


드라이버/문자/tty_io.c : 1087

void tty_write_message(struct tty_struct *tty, char *msg) 
{ 
    lock_kernel(); 
    if (tty) { 
     mutex_lock(&tty->atomic_write_lock); 
     if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) 
      tty->ops->write(tty, msg, strlen(msg)); 
     tty_write_unlock(tty); 
    } 
    unlock_kernel(); 
    return; 
} 


아치/팔/포함/ASM/bitops.h : 37

012 3,516,
static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p) 
{ 
    unsigned long flags; 
    unsigned long mask = 1UL << (bit & 31); 

    p += bit >> 5; 

    raw_local_irq_save(flags); 
    *p |= mask; 
    raw_local_irq_restore(flags); 
} 


드라이버/시리얼/serial_core.c : 2376

static int 
uart_write(struct tty_struct *tty, const unsigned char *buf, int count) 
{ 
    struct uart_state *state = tty->driver_data; 
    struct uart_port *port; 
    struct circ_buf *circ; 
    unsigned long flags; 
    int c, ret = 0; 

    /* 
    * This means you called this function _after_ the port was 
    * closed. No cookie for you. 
    */ 
    if (!state || !state->info) { 
     WARN_ON(1); 
     return -EL3HLT; 
    } 

    port = state->port; 
    circ = &state->info->xmit; 

    if (!circ->buf) 
     return 0; 

    spin_lock_irqsave(&port->lock, flags); 
    while (1) { 
     c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); 
     if (count < c) 
      c = count; 
     if (c <= 0) 
      break; 
     memcpy(circ->buf + circ->head, buf, c); 
     circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); 
     buf += c; 
     count -= c; 
     ret += c; 
    } 
    spin_unlock_irqrestore(&port->lock, flags); 

    uart_start(tty); 
    return ret; 
} 

또한, (3) 문서 사람이 쓰기에서 :

시도가 파이프 나 FIFO에 쓰기 몇 가지 주요 특성이 있습니다 :

  • 원자/비 원자 : A 쓰기 한 작업에서 작성된 전체 금액이 다른 프로세스의 데이터로 인터리브되어 있지 않으면 원자 적입니다. 이 기능은 여러 작성자가 단일 독자에게 데이터를 보내는 경우에 유용합니다. 응용 프로그램은 얼마나 많은 쓰기 요청이 원자 적으로 수행 될 것으로 예상 될 수 있는지를 알아야합니다. 이 최대 값은 {PIPE_BUF}라고합니다. IEEE Std 1003.1-2001의이 볼륨은 {PIPE_BUF} 바이트 이상에 대한 쓰기 요청이 원자 적 (atomic)인지 여부를 나타내지 않지만 {PIPE_BUF} 바이트 이하의 쓰기는 원자 적이어야합니다.
+0

"질문"을 맨 위에 올리면 응답 속도가 더 빨라질 수 있습니다 (일종의 요약). –

+0

팁을 주셔서 감사합니다. -Jayce – user239719

+0

운전자가 정확성을 검증 할 수있는 고문 스트레스 테스트가 정말로 필요한 것 같습니다. 그것은 마치 주변에서 정말 일반적으로 유용 할 것 같습니다. – Omnifarious

답변

3

나는 기술적으로, 장치가 FIFO를하지, 생각, 그래서 당신이 인용 것이 보장이 적용되어 있는지 전혀 분명하지 않다.

부분적으로은 프로세스 내에서 읽고 쓰고 있습니까? 아니면 실제로 다른 프로세스에서 동일한 장치를 읽고 쓰고 있습니까? 후자를 가정하면 어떤 종류의 프록시 프로세스를 구현하는 것이 더 나을 것입니다.프록시는 장치를 독점적으로 소유하고 모든 읽기 및 쓰기를 수행하므로 다중 프로세스 원 자성 문제를 완전히 피할 수 있습니다. 간단히 말해,이 장치에서 읽기/쓰기가 실제로 원자 적 동작인지 확인하지 않으려합니다. 자신감을 가지고 수행하기가 어려우며, 이후 버전의 Linux (또는 다른 OS 모두)가 원 자성을 구현하는 데 실패 할 경우 미묘한 오류가 발생할 수있는 응용 프로그램을 남겨 둡니다.

+0

+1. 소스 코드를 읽거나 현재 버전에 대한 스트레스 테스트를 실행하여 API 보증을 추측하는 것은 실수처럼 들릴 수 있습니다. –

+0

@Dale, 답장을 보내 주셔서 감사합니다. 귀하의 질문에 대한 답변으로는 단 하나의 프로세스 읽기/쓰기가 있지만 읽기/쓰기가 중단없이 이루어 지도록해야합니다. 즉, 인터럽트, 선점, 간섭 할 수있는 모든 것은 쓰기 또는 읽기 작업이 진행되는 동안 중단됩니다. 나는 양도가 trivially 작습니다, 16 비트 또는 가까이에 2의 몇 가지 요인을 믿습니다. 버그가있을 수있는 무언가에 버그가있을 가능성이 있기 때문에 트랜잭션 중재에 대한 자신의 프로세스를 구현하는 데 조심 스럽습니다. 도와 줘서 고마워. – user239719

+0

@Jason 답장을 보내 주셔서 감사합니다. 이 경우 당신은 무엇을 제안합니까? – user239719

2

저는 PIPE_BUF이 옳다고 생각합니다. 이제 PIPE_BUF 바이트 미만의 기록은 아토믹하지 않을 수 있지만 그렇지 않은 경우 OS 버그입니다. OS에 버그가있는 지 물어볼 수 있습니다. 하지만 실제로 그런 버그가있는 경우 즉시 수정해야합니다.

원자로로 PIPE_BUF 개를 쓰고 싶다면 운이 좋았다고 생각합니다. 더 큰 규모의 글쓰기가 원자 적으로 일어나는 지 확인하기 위해 응용 조정과 협력 밖에서 어떤 방법이 있다고 나는 생각하지 않는다.

이 문제의 해결 방법 중 하나는 자신의 프로세스를 장치 앞에두고 장치에 쓰고 자하는 모든 사람이 프로세스에 연결하여 대신 데이터를 전송하는 것입니다. 그런 다음 원 자성 보장 측면에서 애플리케이션에 적합한 모든 것을 할 수 있습니다.

+0

@Omnifarious, 답장을 보내 주셔서 감사합니다. PIPE_BUF에 대한 정의를 확인한 결과 데이터 구조가 임계 값보다 훨씬 낮은 것처럼 보입니다. 나는 기본적으로 알려진 버그에 대해 묻고 있습니다. 나는 또한 내가 사용하고있는 장치의 성격 때문에 더 궁금해한다. 소수의 사람들 만 사용하는 아주 작은 커스터마이징 된 커널을 가진 비표준 하드웨어에서 수백만 명의 사람이 사용할 수있는 데스크탑 배포 코드의 완성도를 신뢰하는 것이 더 쉽습니다. 도와 줘서 고마워, 고마워. – user239719

+0

유닉스 시스템에서는'PIPE_BUF'가 상당히 다르다는 것에주의하십시오. 관측 값에 대한 개요는 다음을 참조하십시오. http://ar.to/notes/posix#pipe-buf –