There are many different types of locking primitives. One interesting distinction is persistence, in other words, whether the lock can exist independently of the address space of the process using the lock.
Non-persistent locks include pthread_mutex_lock(), pthread_rwlock_rdlock(), and most kernel-level locking primitives. If the memory locations instantiating a non-persistent lock's data structures disappear, so does the lock. For typical use of pthread_mutex_lock(), this means that when the process exits, all of its locks vanish. This property can be exploited in order to trivialize lock cleanup at program shutdown time, but makes it more difficult for unrelated applications to share locks, as such sharing requires the applications to share memory.
Persistent locks help avoid the need to share memory among unrelated applications. Persistent locking APIs include the flock family, lockf(), System V semaphores, or the O_CREAT flag to open(). These persistent APIs can be used to protect large-scale operations spanning runs of multiple applications, and, in the case of O_CREAT even surviving operating-system reboot. If need be, locks can span multiple computer systems via distributed lock managers.
Persistent locks can be used by any application, including applications written using multiple languages and software environments. How could similar functionality be provided via transactional memory?
Here are some possibilities:
Of course, the fact that it is called transactional memory should give us pause, as the name itself conflicts with the concept of a persistent transaction. It is nevertheless worthwhile to consider this possibility as an important test case probing the inherent limitations of transactional memory.