berkeley db mutex 的研究

bdb mutex有两种用途:

  1.   作为latch, 保护资源(内存数据结构, 文件操作);
  2.   wait-notifiy. 设置SELF_BLOCK标志位. 用在逻辑锁, group commit时等待.

实现细节:

mux_win32.c 和mut_tas.c的实现类似:

  1. spin, 通过OS机制去 原子tas某lock标志位; 成功则退出. 对win32来说, 是类似 InterlockedExchange的原语. 对tas来说, 使用底层的一些OS tas机制(见 dbinc/mutex_int.h, 搜MUTEX_SET).
  2. spin不成功, 则 等待-重试. win32通过 WaitForSingleObject, tas通过 OS 线程sleep原语;
  3. unlock时清除tas标志位. win32 unlock, 会调用PlusEvent 唤醒等待的线程.

在mut_pthread.c 中, 不去spin:

  1. 调用pthread_mutex_lock 拿到mutex lock.
  2. 如SELF_BLOCK, 通过pthread_cond_wait 做wait.
  3. unlock时, 调用pthread_mutex_unlock. 如SELF_BLOCK, 调用pthread_cond_signal.

 Memory Barrier语义支持

  • tas中调用MEMBAR_ENTER/EXIT(), 封装了底层OS的mb原语.
  • InterlockedExchange/pthread lock自身会提供membar语义. 

多进程支持

  • mutex对应的内存都在 共享内存中.
  • pthread会设置PTHREAD_PROCESS_SHARED, 提供多进程支持.


关于SELF_BLOCK

SELF_BLOCK语义: 初始化mtx后, 马上lock一次. 再一次 lock则当前线程(可以不是第一次lock的线程)被锁住. 

win32/tas:

通过tas 标志位. 因为mtx标志位已经设置, 再次lock会spin-wait-retry不断重复;

pthread:

仅使用pthread_mutex_lock无法满足self block. 如果同一个线程两次 lock同一mtx, 根据参数, 可能会deadlock, return error, 成功, undefined; 一个线程去unlock另一个线程 lock的mtx, 也会 error或undefined. 

http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_mutex_lock.html

而且 文档提到: Mutexes are expected to be locked only for a few instructions.

所以必须使用conditional variable:
http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html
基本上, condition的工作原理 和java的wait-notify完全(完全么?)一致:

  • condition wait前 当前线程必须已经拿到 mutex 锁, 否则undefined;
  • condition wait block 当前线程. 并释放mutex锁.
  • wait被notify, broadcast唤醒(java notify, notify all?)
  • 线程被唤醒在从wait返回前, 需要拿到 mtx锁, 过程和 pthread_mutex_lock一样. 没拿到被block.
  • wait必须放在while(predict) 里.
mtx:   locked                                       unlocked
T1:                lock并被block.                                       得到mtx锁
T2:                                    unlock mtx             唤醒T1

最终 mtx还是锁住的状态.

见log_put.c, log_flush_int(),  commit->mtx_txnwait 被获得后, 不会释放掉. 

lock.c, lockp->mtx_lock

posted @ 2016-03-03 12:28  brayden  阅读(282)  评论(0编辑  收藏  举报