论坛首页 编程语言技术论坛

Postgresql源码中spinlock的基础:TAS

浏览 2793 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-02-07   最后修改:2010-02-07
PostgreSQL中使用spinlock来对资源进行加锁。TAS lock是最简单的spinlock。当然spinlock可以用信号量来实现。但是据PostgreSQL的早期报告显示,内核提供的信号量将大大降低性能。所以学习TAS lock对我们提高软件性能是大有帮助的。
TAS就是Test And Set。它要做的就是跟一个变量进行Test。如果条件满足对其Set另外一个值,如果条件不满足,就继续等待。但是所有这些都是原子操作。
void spin_lock(lock)
{
  while(test_and_set(lock,true))
   ;
}

void spin_unlock(lock)
{
  atomic_set(lock,false);
}

Windows提供了一个API:InterlockedCompareExchange。PostgreSQL的Windows版本就是利用它来实现TAS的。
下面的Demo就是看看这个API是怎么用的。
#include <windows.h>
#include <iostream>

using namespace std;

void main()
{
	LONG source = 1;

	cout<<"before: "<<source<<endl;

	for(;;)
	{
		if(1==InterlockedCompareExchange(&source,2,1))
		{
			break;
		}
	}

	cout<<"after: "<<source<<endl;
}

PostgreSQL是如何定义TAS的呢?
typedef LONG slock_t;
#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
   发表时间:2010-02-10  
1 spinlock和信号量本身就是两个东西。spinlock就是纯userspace的lock。信号量是内核的,不能用信号量实现spinlock
2 InterlockedCompareExchange有barrier么?你那个source是不是还要volatile?
0 请登录后投票
   发表时间:2010-02-10  
1.是否能用信号量实现spinlock,我还不确定。但是用内核对象会增加CPU时间,其中一个重要的原因是Cache失配率会陡增。
2.InterlockedCompareExchange()带有全局的内存栅障,所以不用volatile。PostgresSQL也麽可有用volatile。
0 请登录后投票
   发表时间:2010-04-21  
spinlock不会增加cpu时间吗?不会有比spinlock性能更低的写法了吧?
0 请登录后投票
   发表时间:2010-04-21  
This function generates a full memory barrier (or fence) to ensure that memory operations are completed in order.
0 请登录后投票
   发表时间:2010-04-21  
这个东东看过好多种实现,如果预计锁的时间比较长,感觉还是不用这处方法。
好像有的地方会在interlock之间加些像pause之类的汇编指令。
0 请登录后投票
   发表时间:2010-04-21  
对我们大部分人来说,无需要考虑像CRITICALSECTION的性能问题。
0 请登录后投票
   发表时间:2010-04-23   最后修改:2010-04-23
spinlock 会导致一种 liveness hazard的现象。。都在频繁等待其他线程......
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics