title: Taking a semaphore must be atomic. Is Pintos's sema_down safe?
body: <p>This piece of code comes from Pintos source:
  <a href="https://www.cs.usfca.edu/~benson/cs326/pintos/pintos/src/threads/synch.c" rel="nofollow">https://www.cs.usfca.edu/~benson/cs326/pintos/pintos/src/threads/synch.c</a></p>
  
  <pre><code>void
  sema_down (struct semaphore *sema) 
  {
    enum intr_level old_level;
  
    ASSERT (sema != NULL);
    ASSERT (!intr_context ());
  
    old_level = intr_disable ();
    while (sema-&gt;value == 0) 
      {
        list_push_back (&amp;sema-&gt;waiters, &amp;thread_current ()-&gt;elem);
        thread_block ();
      }
    sema-&gt;value--;
    intr_set_level (old_level);
  }
  </code></pre>
  
  <p>The fact of taking a semaphore is <code>sema-&gt;value--;</code>. If it works it must be an atomic one operation.
  How can we know that it is atomic operation in fact? I know that modern CPU guarantees that aligned memory operation ( for word/doubleword/quadword- it depends on) are atomic. But, here, I am not convinced why it is atomic.</p>