The Origin of Concurrent Programming: From Semaphores To Remote Procedure Calls