クリティカルセクション

なぜか他のPCでは再現性のないデッドロック問題が。(PC名:センターで問題発生)
こんな簡単なプログラムでデッドロック起きるか?って感じだし、第一クリティカルセクションひとつでデッドロックするってどういうことだろ?
片方がEnterCriticalSectionして、もう片方がLeaveCriticalSectionして固まってるらしい。この組み合わせで固まるってどういう状態なんだろ。

#include <windows.h>
#include <process.h>

typedef struct {
  HWND hWnd;
  CRITICAL_SECTION cs;
} THREADPARAM;

int iCount;

DWORD WINAPI ThreadFunc1(LPVOID pvParam) {
  THREADPARAM * tp = (THREADPARAM *)pvParam;

  for (int i = 0; i < 100000; i++) {
    EnterCriticalSection(&tp->cs);
    for (iCount = 0 ; iCount < 100 ; iCount++) {
    }
    LeaveCriticalSection(&tp->cs);
    Sleep(0); // これ追加したら更にめっちゃデッドロック
  }
  ExitThread(TRUE);
}

DWORD WINAPI ThreadFunc2(LPVOID pvParam) {
  THREADPARAM * tp = (THREADPARAM *)pvParam;

  for (int i = 0; i < 100000; i++) {
    EnterCriticalSection(&tp->cs);
    for (iCount = 0 ; iCount > -100 ; iCount--) {
    }
    LeaveCriticalSection(&tp->cs);
    Sleep(0);
  }
  ExitThread(TRUE);
}

int main(void) {
  DWORD dwParam;
  THREADPARAM tp;

  InitializeCriticalSection(&tp.cs);
  HANDLE h1 = CreateThread(
    NULL , 0 , ThreadFunc1 , &tp , 0 , &dwParam);
  HANDLE h2 = CreateThread(
    NULL , 0 , ThreadFunc2 , &tp , 0 , &dwParam);
  WaitForSingleObject(h1, INFINITE);
  WaitForSingleObject(h2, INFINITE);
  DeleteCriticalSection(&tp.cs);
  return 0;
}