>
이 코드는 Pintos 소스에서 온 것입니다. https : //www.cs.usfca. edu/~ benson/cs326/pintos/pintos/src/threads/synch.c

void
sema_down (struct semaphore *sema) 
{
  enum intr_level old_level;
  ASSERT (sema != NULL);
  ASSERT (!intr_context ());
  old_level = intr_disable ();
  while (sema->value == 0) 
    {
      list_push_back (&sema->waiters, &thread_current ()->elem);
      thread_block ();
    }
  sema->value--;
  intr_set_level (old_level);
}

세마포어를 복용하는 사실은 sema->value--; 입니다. . 작동하는 경우 원 자성 작업이어야합니다. 그것이 실제로 원자 작동이라는 것을 어떻게 알 수 있습니까? 현대 CPU는 정렬 된 메모리 작업 (단어/더블 워드/쿼드 워드의 경우)이 원자적임을 보장합니다. 그러나, 나는 그것이 왜 그것이 원자 적인지 확신하지 못한다.


  • 답변 # 1

    TL : DR : DMA를 사용하여 메모리를 관찰하는 시스템 장치를 계산하지 않는 한 UP 시스템에서 인터럽트가 비활성화 된 상태라면 아무 문제가 없습니다

    .

    intr_disable (); 참고  / intr_set_level (old_level);  작업 주위에.

    <시간> 와이즈 비즈

    멀티 스레드 옵저버의 경우 읽기-수정-쓰기 작업이 아닌또는개별로드에만 적용됩니다.

    <시간>

    원자가되기 위해서는 관심있는 관찰자가 무엇을 고려해야하는지고려해야합니다. 중요한 것은 작업이 부분적으로 발생한 것으로 아무것도관찰할 수 없다는 것입니다. 이를 달성하는 가장 간단한 방법은 작업이 물리적/전기적으로 순간적으로 이루어지고 모든 비트에 동시에 영향을주는 것입니다 (예 : 병렬 버스의로드 또는 저장은 클럭 사이클의 경계에서 시작되지 않은 상태에서 완료된 상태로 진행됨). 그것은 병렬 버스의 너비까지 "무료"원자입니다). 읽기-수정-쓰기는 불가능합니다. 여기서 관찰자가 부하와 상점을 보지 못하게하는 것이 최선입니다.

    x86의 Atomicity에 대한 나의 대답은 원 자성이라는 것이 무엇을 의미하는지에 대해 같은 방식으로 다른 방식으로 설명했습니다.

    <시간>

    유니 프로세서 (UP) 시스템에서유일한 비동기 관찰자는 다른 시스템 장치 (예 : DMA) 및 인터럽트 처리기입니다. CPU가 아닌 관찰자가 세마포어에 쓰지 못하게 할 수 있다면, 우리가 관심을 갖는 인터럽트와 관련하여 원자 성일뿐입니다.

    이 코드는 손쉬운 방법으로 인터럽트를 비활성화합니다. 그럴 필요는 없습니다 (적어도 우리가 asm으로 쓰는 경우는 아닙니다).

    인터럽트는 명령 중간에 두 명령 사이에서 처리되지 않습니다. 기계의 구조적 상태는 메모리 감소를 포함하거나 포함하지 않습니다.

    modern CPU guarantees that aligned memory operation are atomic

     달렸거나 그렇지 않았다. 우리는 실제로 dec [mem] 가 필요하지 않습니다  이것을 위해.

    BTW, 이것이 lock dec [mem] 의 유스 케이스입니다.   cmpxchg 없이  접두사. 난 왜 그들이 왜 그냥 lock 을하지 않았는지 궁금   lock 에 암시 적 UP 시스템은 종종 cmpxchg 가 필요하지 않기 때문입니다.  접두사.

    <시간>

    컴파일러가 lock 를 방출하도록하는 확실한 방법은 없습니다  이와 같은 대신에 :

    dec [value]
    
    
    C11/C ++ 11은 시그널 핸들러/인터럽트와 관련하여 원 자성을 요청하는 방법을 제공하지는 않지만 다른 스레드는 제공하지 않는다고 생각합니다. 그들은 mov eax, [value] ;; interrupt here = bad dec eax ;; interrupt here = bad mov [value], eax 를 제공합니다  컴파일러 장벽으로, x86에서 atomic_signal_fence 를 피할 수있는 유형을 기억하지 못합니다.  여전히 원자 유형의 다른 의미론을 가지고 있지만 접두사.

    C11/C ++ 11 lock  이 아이디어를 염두에두고 있지만 RMW가 아닌 별도의로드/스토어에만 원 자성을 제공합니다. volatile sig_atomic_t 의 typedef입니다.  x86 Linux에서. 표준의 인용문은 해당 질문을 참조하십시오.

    int

  • 이전 java - 최대 절전 모드 내장 가능 - 구성 요소 속성을 찾을 수 없습니다
  • 다음 winapi - Turbo-C를 사용하는 C의 Windowsh