NIIBE Yutaka
gniib****@m17n*****
2005年 9月 2日 (金) 10:56:20 JST
On Thu, 1 Sep 2005 02:14:28 -0700 Jun Inoue <jun.l****@gmail*****> wrote: > 応投げてみます。ミソは sig_atomic_t より小さいオブジェクトの read/write > は atomic であると仮定するというところです。[1]によれば、大抵の環境では > ポインタは atomic object のようなので、これでロックが減らせると思ったん > ですが、ちょっとキモいですかね… > > [1] "The GNU C Library" http://www.delorie.com/gnu/docs/glibc/libc_496.html uim のコードとしては、単にロック無しにするのが良いと思われますけれども。 えーと、[1] の記述は必ずしも正しくないと思います。sig_atomic_t がアト ミック, ポインタアクセスがアトミックという二つの言明は正しいけど、小さ い int 型ではアトミックは保証されないと思います。 よって、サイズを見て小さければアトミックであるという今回の uim の追加 はよろしくないかもしれません。 short int のアクセスが atomic でないという実例を Alpha で見てみましょう。 参考: Alpha のインストラクションセット http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS31D-TET1_html/asm4.html ------------------ テストプログラム t.c int a; short int b; void func(void) { a = 1; b = 2; } ------------------ を gcc -S t.c でコンパイル。 変数 a のアクセスは 1 をそのまま atomic にメモリに書き込んでいます。 が、変数 b のアクセスはメモリを読んで or してメモリに書くという形で アトミックではありません。 ------------------ Alpha でのアセンブリコード /**/ は gniibe の注釈 .set noat .set noreorder .set nomacro .text .align 2 .globl func .ent func func: .eflag 48 .frame $15,16,$26,0 .mask 0x4008000,-16 ldah $29,0($27) !gpdisp!1 lda $29,0($29) !gpdisp!1 $func..ng: lda $30,-16($30) stq $26,0($30) stq $15,8($30) mov $30,$15 .prologue 1 ldq $2,a($29) !literal /* レジスタ $2 に変数 a のアドレス */ lda $1,1($31) /* レジスタ$1 := 1 */ stl $1,0($2) /* レジスタ$2 の指すところにレジスタ $1 を書き込む */ ldq $3,b($29) !literal /* レジスタ $3 に変数 a のアドレス */ lda $4,2($31) /* レジスタ$4 := 2 */ ldq_u $2,0($3) /* レジスタ$3 のアドレスを64-bitアクセスで読み込み */ mov $3,$1 /* レジスタ$1 := レジスタ$3 */ mskwl $2,$1,$2 /* レジスタ$2 := レジスタ$2 の low word の mask */ inswl $4,$1,$1 /* レジスタ$1に レジスタ$4 の low word を insert */ bis $1,$2,$1 /* レジスタ$1 := レジスタ$1 ior レジスタ$2 */ stq_u $1,0($3) /* レジスタ$3のアドレスに64-bitアクセスで書き込み */ mov $15,$30 ldq $26,0($30) ldq $15,8($30) lda $30,16($30) ret $31,($26),1 .end func .comm a,4,4 .comm b,2,2 .section .note.GNU-stack,"", @ progbits .ident "GCC: (GNU) 3.3.5 (Debian 1:3.3.5-13)" --