InnoDB定义的Mutex--01

InnoDB定义的Mutex

    InnoDBib0mutex.h文件中定义了六种自定义的Mutex如下:

OSBasicMutexOSEvent定义的Mutex,依赖于具体的OS;施加锁只尝试一次。如下面的初始化代码段等。

OSTrackMutex:继承自OSBasicMutex,依赖于OS;施加锁尝试函数参数指定的次数(max_spins参数指定尝试的次数)。

TTASFutexMutex:利用OSCAS原子指令实现锁的施加尝试,利用TAS实现解锁尝试。适用于LinuxFutex机制[1]

TTASMutex 利用OSTAS原子指令实现锁的施加和解锁尝试,在尝试不成的情况下,进行忙等待。

TTASEventMutex:利用OSTAS原子指令实现锁的施加和解锁尝试,在尝试不成的情况下,每次尝试之间需要调用ut_delay()进行睡眠延迟,尝试指定的次数(max_spins参数指定尝试的次数),且最终还要等到锁为止。

PolicyMutex:获得锁,且获得施加锁者,主要用于Performance schema监控。

    OSBasicMutex的初始化init()函数的代码段需要区分操作系统,相应的enter()destroy()exit()等函数也需要区分操作系统,根据不同的操作系统调用不同操作系统的相应函数:

#ifdef _WIN32

    InitializeCriticalSection((LPCRITICAL_SECTION) &m_mutex);  //Mutex的定义依赖于WindowsInitializeCriticalSection()函数

#else

    {

        int    ret;

        ret = pthread_mutex_init(&m_mutex, MY_MUTEX_INIT_FAST); //Mutex的定义依赖于Posix Threadpthread_mutex_init()函数

        ut_a(ret == 0);

    }

#endif /* _WIN32 */

    OSBasicMutex的测试锁是否施加try_lock()函数的代码段如下:

    /** @return true if locking succeeded */

    bool try_lock() UNIV_NOTHROW

    {

        ut_ad(innodb_calling_exit || !m_freed);

#ifdef _WIN32

        return(TryEnterCriticalSection(&m_mutex) != 0);  //Mutextrylock依赖于Windows函数

#else

        return(pthread_mutex_trylock(&m_mutex) == 0);    //Mutextrylock依赖于Posix Thread

#endif /* _WIN32 */

    }

 

    TASCAS原子操作的定义如下:

#ifdef _WIN32

# define TAS(l, n)      os_atomic_test_and_set_u32((l), (n))    //Windows下利用Test And Set原子操作实现TAS操作

#else

# define TAS(l, n)      os_atomic_test_and_set_ulint((l), (n))  //Windows下利用Test And Set原子操作实现TAS操作(如Linux下调用__sync_lock_test_and_set()系统函数实现自旋锁,PostgreSQL也同样地调用了类似的函数)

#endif /* _WIN32 */

#define CAS(l, o, n)    os_val_compare_and_swap_ulint((l), (o), (n))  //不同OS下利用Compare And Exchange原子操作实现CAS操作

 

    InnoDB主要定义了如下类型的系统锁:

typedef  ib_mutex_t  RsegMutex;     //保护回滚段的系统锁

typedef  ib_mutex_t  TrxMutex;      //保护事务块的系统锁,这是单个事务的事务块的内容保护

typedef  ib_mutex_t  UndoMutex;     //保护UNDO日志的系统锁

typedef  ib_mutex_t  PQMutex;       //保护PURGE QUERY的系统锁

typedef  ib_mutex_t  TrxSysMutex;   //保护整个InnoDB系统级的全局事务信息的系统锁,这是全局系统内所有在运行的事务的整体信息保护

typedef  ib_mutex_t  LockMutex;     //保护锁表的系统锁

    ib_mutex_t”如下又分别有多种可能,可能被前面描述的六种Mutex的其中之一根据宏定义[2]进行选择而定义。

# ifdef HAVE_IB_LINUX_FUTEX

typedef PolicyMutex<TTASFutexMutex<DebugPolicy> > FutexMutex;

# endif /* HAVE_IB_LINUX_FUTEX */

 

typedef PolicyMutex<TTASMutex<DebugPolicy> > SpinMutex;

typedef PolicyMutex<TTASEventMutex<DebugPolicy> > SyncArrayMutex;

 

typedef PolicyMutex<OSTrackMutex<DebugPolicy> > SysMutex;

typedef PolicyMutex<OSBasicMutex<DebugPolicy> > EventMutex;

 

#ifdef MUTEX_FUTEX

/** The default mutex type. */

typedef    FutexMutex    ib_mutex_t;

#define MUTEX_TYPE      "Uses futexes"

#elif defined(MUTEX_SYS)

typedef    SysMutex    ib_mutex_t;

#define MUTEX_TYPE      "Uses system mutexes"

#elif defined(MUTEX_EVENT)

typedef    SyncArrayMutex    ib_mutex_t;

#define MUTEX_TYPE      "Uses event mutexes"

#else

#error "ib_mutex_t type is unknown"

#endif /* MUTEX_FUTEX */

 



[1] FutexFast Userspace muTexes的缩写,被Linux 2.5.7支持。Futex是用户态与内核态混合的同步机制,同步的进程间通过mmap共享一段内存,futex变量位于这段共享的内存中且操作是原子的,当进程尝试进入互斥区或者退出互斥区的时候,先查看共享内存中的futex变量,如果没有竞争发生,则只修改futex,而不用再执行系统调用,这样会比没有Futex机制总是需要进入内核态做判断更高效。

[2] innodb.cmake文件中定义如下内容:

IF(MUTEXTYPE MATCHES "event")

  ADD_DEFINITIONS(-DMUTEX_EVENT)

ELSEIF(MUTEXTYPE MATCHES "futex" AND DEFINED HAVE_IB_LINUX_FUTEX)

  ADD_DEFINITIONS(-DMUTEX_FUTEX)

ELSE()

   ADD_DEFINITIONS(-DMUTEX_SYS)

ENDIF()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值