Run-time detection of potential deadlocks for programs with locks, semaphores, and condition variables