Thread and concurrency support benefited by message passing with IPC mechanisms since tasks now consisted of multiple code threads which Mach could freeze and unfreeze during message handling. This allowed the system to be distributed over multiple processors, either using shared memory directly as in most Mach messages, or by adding code to copy the message to another processor if needed. In a traditional kernel this is difficult to implement; the system has to be sure that different programs don't try to write to the same memory from different processors. However, Mach ports, its process for memory access, make this well defined and easy to implement, and were made a first-class citizen in that system.