title: Futexes and blocking in the kernel
body: <p>I was reading some documentation and trying out a few samples of code that issue the <code>futex</code> system call in Linux. I read that if a mutex is acquired by <code>thread_a</code> using <code>FUTEX_LOCK_PI</code>, and say if another thread <code>thread_b</code> tries to acquire the same, the latter(<code>thread_b</code>) is blocked in the kernel.</p>
  
  <p>What exactly is meant by "blocked in the kernel"? Is it that the execution of <code>thread_b</code> in userspace does not resume? In the following example, the second thread seems to issue the printf after the syscall as well. Would that not suggest that it is not blocked in the kernel? What am I missing?</p>
  
  <pre><code>/*
   * This example demonstrates that when futex_lock_pi is called twice, the
   * second call is blocked inside the kernel.
   */
  
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;pthread.h&gt;
  
  int mutex = 0;
  
  #define  __NR_futex          240
  #define FUTEX_WAIT 0
  #define FUTEX_WAKE 1
  #define FUTEX_FD 2
  #define FUTEX_REQUEUE 3
  #define FUTEX_CMP_REQUEUE 4
  #define FUTEX_WAKE_OP 5
  #define FUTEX_LOCK_PI 6
  #define FUTEX_UNLOCK_PI 7
  #define FUTEX_TRYLOCK_PI 8
  #define FUTEX_WAIT_REQUEUE_PI 11
  #define FUTEX_CMP_REQUEUE_PI  12
  
  
  void *thread(void *arg) {
    int ret = 0;
    pid_t tid = gettid();
    printf("Entering thread[%d]\n", tid);
  
    ret = syscall(__NR_futex, &amp;mutex, FUTEX_LOCK_PI, 1, NULL, NULL, 0);
    printf("Thread %d returned from kernel\n", tid);
    printf("Value of mutex=%d\n", mutex);
    printf("Return value from syscall=%d\n", ret);
  }
  
  int main(int argc, const char *argv[]) {
    pthread_t t1, t2;
  
    if (pthread_create(&amp;t1, NULL, thread, NULL)) {
      printf("Could not create thread 1\n");
      return -1;
    }
  
    if (pthread_create(&amp;t2, NULL, thread, NULL)) {
      printf("Could not create thread 2\n");
      return -1;
    }
  
    // Loop infinitely
    while ( 1 ) { }
  
    return 0;
  }
  </code></pre>
  
  <p>The output can be found below :-</p>
  
  <pre><code>Entering thread[952]
  Thread 952 returned from kernel
  Entering thread[951]
  Value of mutex=-2147482696
  Return value from syscall=0
  Thread 951 returned from kernel
  Value of mutex=-1073740873
  Return value from syscall=0
  </code></pre>