Foundations of Parallel Programming