I’ve already introduced you to shared memory synchronization. Lock is a primitive and particularly the mutual exclusion lock is a primitive that is used ubiquitously in writing shared memory parallel programs to protect data structure so that one thread can exclusively modify the data and release the lock so that another thread can inspect the data later on and so on. And similarly, barrier synchronization is another synchronization primitive that is very popular in scientific programs and we have covered both of these in fairly great detail in talking about what the operating system has to do in order to have efficient implementation of locks as well as barriers. Now the up shot is, if you are writing a shared memory program, there are two types of memory accesses that are going to happen. One type of memory access is the normal reads and writes to shared data that is being manipulated by a particular thread. The second kind of memory access is going to be for synchronization variables that are used in implementing locks and barriers by the operating system itself. It may be the operating system, or it could be a user level threads library that is providing these mutual exclusion locks, or barrier primitives, but in implementing those synchronization primitives, those algorithms are going to use reads and writes to shared memory. So there are two types of shared memory accesses going on in the execution of a parallel program. One is access to normal shared data and the other is access to synchronization variables.