Asserting and checking determinism for multithreaded programs