Test-And-Set操作について

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 は同じ関係にあるので,実装も基本的に同じになる.