test and set 操作について復習をしたのでメモ.
test and set (TAS)操作では,次のような処理をアトミックに行う.
int test_and_set(int *mem){ old = *mem; if (0 == *mem){ *mem = 1; }else{ /* do nothing */ } return old; }
例えば 2.6系のlinux (i386)だと test and set 操作は linux/include/asm-i386/atomic.h にて実装されている.具体的には,インラインアセンブラで記述されており, LOCK 命令を使いバスをロックすることでアトミックな処理を実現している.
この test and set 操作を使うと同期機構が実現できる.以下,いくつか例を示す.
test-and-set操作を使った排他制御の実装例
volatile int lock=0; /* 0:unlock 1:locked */ void lock(int *lock){ while (test_and_set(lock) == 1) ; } void unlock(int *lock){ *lock = 0; }
test-and-set操作を使った同期の実装例
volatile int s=1; void wait(int *s){ while (test_and_set(s) == 1) ; } void signal(int *s){ *s = 0; }
lock/wait と unlock/signal は同じ関係にあるので,実装も基本的に同じになる.