Mac OS X で pthread_mutex_lock と pthread_mutex_unlock の回数がずれる話

  • 2059 回 lock (wait からの復帰も含まれる) され
  • 59 回 wait し
  • 2000 回 unlock され
  • 1966 回 block したことがわかります
pthread でキューを作る(再挑戦)。ついでに dtrace でスレッドの解析 - IT戦記

pthread_mutex_lock = pthread_cond_wait + pthread_mutex_unlock の回数になっているのは、Mac OS X の pthread_cond_wait の設計がそうなっているから。(http://www.opensource.apple.com/darwinsource/, fxr.watson.org: xnu-792 sys/osfmk/kern/sync_sema.c)

831 /*
832  *      Routine:        semaphore_wait_signal
833  *
834  *      Atomically register a wait on a semaphore and THEN signal
835  *      another.  This is the in-kernel entry point that does not
836  *      block at a continuation and does not free a signal_semaphore
837  *      reference.
838  */
839 kern_return_t
840 semaphore_wait_signal(
841         semaphore_t             wait_semaphore,
842         semaphore_t             signal_semaphore)
<<|

pthread_cond_wait の仕事は、mutex を unlock (して他のスレッドを wake)、 cond を待ち受け、mutex を lock の3つだけど、このように、wake と待ち受けをマージした Mach コールが準備されている。だから mutex の unlock 処理は pthread_cond_wait 内で展開して書かれていて、一方 pthread_mutex_lock は普通に呼び出されている。結果、回数がずれる。

ということを理解しました。ちなみに linux はそういう feature-rich な仕組みは使ってないっぽい。オーバーヘッドが小さいからどうでもいいのかな。