WL#6044: InnoDB: Policy-based mutex

Status: Complete

Background
==========
InnoDB makes a distinction between OS mutexes fast_mutex_t (e.g., POSIX on 
Unices and CRITICAL_SECTION on Windows) and a home brew version (ib_mutex_t). 
You cannot mix the two together. The ib_mutex_t use ranking/ordering to make it 
easy to check for deadlocks if #UNIV_SYNC_DEBUG is defined. There is no such 
check for fast_mutex_t. ib_mutex_t is used for all core code synchronisation. 
There are two configuration variables that control the behaviour of ib_mutex_t. 
ib_mutex_t is implemented as a Test and Test And Set mutex And Wait (TTASAW).

 * innodb_spin_wait_delay maps to global variable srv_n_spin_wait_rounds
   This variable sets the upper bound on the delay after the Test

 * innodb_sync_spin_loops maps to global variable srv_spin_wait_delay
   This variable controls the number of spins of the Test.

All ib_mutexe_t instances are controlled by these two variables. If the thread 
fails to acquire the mutex then it is forced to wait on a condition variable 
that is attached to the ib_mutex_t. When the the mutex is free all threads are 
woken up  via a broadcast signal on the condition variable. One of the threads 
will end up acquiring the mutex and the remaining threads will have to go 
through the TTAS and Wait cycle again, and so on.

The Problem
===========
There are several issues with this:

 1. Thundering herd due to the broadcast

 2. Two global variables that control all instances

 3. Size overhead due to condition variable that is part of the ib_mutex_t
    This has been noted as a concern for very large buffer pools. Each block in 
the buffer pool has a mutex attached to it. Therefore the smaller the block size 
the higher the overhead.

 4. Different subsystems have different requirements.

 5. Not flexible
    i. Monitoring is cumbersome

    ii. Can't switch between OS mutex and ib_mutex_t, where we know that the OS 
implementation performs better than the homegrown version.

    iii. Cannot use mutexes with different characteristics in different parts of 
the code. e.g., use a wait mechanism based on a futex on Linux instead of the 
condition variable

 6. The code is not generic, it cannot be used as a library

The solution
============
 1. Have one mutex type, the OS mutex and any homebrew mutexes are subtypes of 
this generic type

 2. Use static inheritance (templates) to reduce vptr overhead. This is mainly 
for the buffer pool block mutexes. Otherwise dynamic inheritance should be OK 
too.

 3. Decouple the code from InnoDB so that it can be used as a library.

 4. Make it easy to add new policies and make it easy to customise mutex 
behaviour.