PostgreSQL V9.6 LWLock实现分析(五)

LWLock实现的技术

    上一节,我们介绍了LWLock的数据结构,其中LWLock锁的“state”上的锁标志可以有两种模式,如下:

typedef enum LWLockMode

{

    LW_EXCLUSIVE,  //排他模式

    LW_SHARED,     //共享模式

    LW_WAIT_UNTIL_FREE    /* A special mode used in PGPROC->lwlockMode,

                           * when waiting for lock to become free. Not

                           * to be used as LWLockAcquire argument */

} LWLockMode;

    LWLock结构体定义了state标志位(LWLock的数据结构参见上一节),此标志位是通过LWLockAcquire ()LWLockAttemptLock()函数调用完成标志位设置的。

LWLockAttemptLock(LWLock *lock, LWLockMode mode)

{...

    old_state = pg_atomic_read_u32(&lock->state);  //读出锁的原始值

    while (true)

    {...

        desired_state = old_state; //desired_state上先保持旧值

        if (mode == LW_EXCLUSIVE)

        {

            lock_free = (old_state & LW_LOCK_MASK) == 0;

            if (lock_free)

                desired_state += LW_VAL_EXCLUSIVE;  //desired_state上先保持旧值后,根据锁的模式加排它锁的标识

        }

        else

        {

            lock_free = (old_state & LW_VAL_EXCLUSIVE) == 0;

            if (lock_free)

                desired_state += LW_VAL_SHARED; //desired_state上先保持旧值后,根据锁的模式加共享锁的标识

        }

        //desired_state成为在锁标志位上将被设置的值。pg_atomic_compare_exchange_u32()完成设置标志位(不同硬件平台,设置方式不同)

        if (pg_atomic_compare_exchange_u32(&lock->state, &old_state, desired_state))   

        {

...

        }

    }

...

}

    pg_atomic_compare_exchange_u32()函数调用的其它函数,因硬件平台而异,如Windows下,调用栈如下,最终使用了InterlockedCompareExchange()函数完成锁标志位的置位工作,state标志位被设置为“LW_VAL_SHARED”或“LW_VAL_EXCLUSIVE”。

LWLockAcquire()

  LWLockAttemptLock()

    pg_atomic_compare_exchange_u32()

      pg_atomic_compare_exchange_u32_impl()   

        InterlockedCompareExchange() //把目标操作数(第1参数所指向的内存中的数)与一个值(第3参数)比较,如果相等,则用另一个值(第2参数)与目标操作数(第1参数所指向的内存中的数)交换

    另外,释放锁时也需要对锁标志位置位为“LW_FLAG_RELEASE_OK”,且无“LW_VAL_SHARED”也无“LW_VAL_EXCLUSIVE”,置位操作通过pg_atomic_sub_fetch_u32()函数完成,如下是在Windows下的调用栈示例。

LWLockRelease()

  pg_atomic_sub_fetch_u32()

    pg_atomic_sub_fetch_u32_impl()

      pg_atomic_fetch_sub_u32_impl()

        pg_atomic_fetch_add_u32_impl()

          InterlockedExchangeAdd() //用于对一个32位数值执行加法的原子操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值