A lightweight deadlock analysis for programs with threads and reentrant locks