- satoh_fumiyasu
- 1162
- 0
- 0
- 0
Samba の tevent という実装にシグナルハンドラー内で uint32_t な変数に加算、イベント処理ループなどでそれを参照しているんだけど、どれくらいヤバい? sig_atomic_t に変えるだけで直るかな…。
2014-05-28 12:03:36sig_atomic_t のアトミック性がどんな操作にあてはまるのか把握してないマン。tevent のコードはいわゆる 32bit 以上の CPU+OS なら uint32_t がアトミックな操作できると想定しているようだけど、これは駄目だよね。
2014-05-28 12:07:49@satoh_fumiyasu volatileにしとけば、同一CPUコアからなら見えます。他コアにも即座に見せようとしたら、メモリバリアが必要。uint32_tなら、おそらくsig_atomic_t的にはまあOKでしょう。(sig_atomic_tにした方がいいけど)
2014-05-28 12:16:01@n_soda そうそう、volatile にもなってないんですよね。それと uint32_t の変数は構造体の一部で、構造体をメンバー変数ごとでなく丸ごとコピーしたりするのがバグってる原因かなーと想像しているところです。ほかの人に見てもらっているので詳細は不明ですが…。
2014-05-28 12:21:59@koie C で n++; とかすると、アトミックでない機械語になる可能性があるってことですかね。加算するのはシグナルハンドラー内だけで、それ以外では参照だけしているので、それなら大丈夫…かな。いや駄目か?? うーん。
2014-05-28 12:24:25@satoh_fumiyasu @koie 複数の異なるシグナルハンドラで n++ してなければ、そこは大丈夫でしょう。
2014-05-28 12:26:09@satoh_fumiyasu 普通はアトミックな命令は生成しないと思います、遅いので。 ループ変数はレジスタに乗ってなかったらvolatile指定してなくても動いちゃいそう。
2014-05-28 12:27:30@koie @satoh_fumiyasu 参照する側が、適切なタイミングでpthread APIを呼び出してれば、そのタイミングでメモリにも書くのでvolatile要らないし、バリアもpthread API側で発行してくれるので不要ですね。
2014-05-28 12:27:42@n_soda @koie 複数のシグナルハンドラーで同一インスタンスである sig_state->got_signal->count を ++ してますぅ…。駄目ですか? シグナルハンドラー実行中に別のシグナルハンドラーが割り込むことってあるんでしたっけ。(よく知らない
2014-05-28 12:29:50@n_soda @koie あ、「複数のシグナルハンドラー」でなく、ある一つにシグナルハンドラーをすべてのシグナルのハンドラーとして登録しています。その中で sig_state->got_signal->count++ してます。
2014-05-28 12:31:07@satoh_fumiyasu @koie 現在実行中のシグナルと同一のシグナルは保留されますが、他のシグナルは入ります。なのでシグナルハンドラが同一関数でも、シグナルが異なれば、atomicであるという保証はないです。→atomic API使うか、さもなくば変数を分けるか
2014-05-28 12:37:28@n_soda @satoh_fumiyasu SA_NODEFERつけたりふるいBSDつかったりすればシグナルハンドらに催乳してくるんじゃないでしょうか。ハンドら実行中にシグナルうけたくなかったらsa_mask設定しないと。
2014-05-28 12:46:47@koie @satoh_fumiyasu SA_NODEFERだとダメでしょうね。古いBSDの方は、ハンドラ実行中はブロックしてるんじゃないかな。
2014-05-28 12:54:16@koie ありがとうございます。arm で発生して amd64 では発生しない→amd64(x86?)ではメモリ内の値を加算する命令がある(らしい)、ということみたいです。
2014-05-28 12:54:19@satoh_fumiyasu @koie <atomic.h>があるOSなら、それを使うのが安全ですが、必ずしもないのが問題ですね。
2014-05-28 13:00:48sig_atomic_t のアトミック性、参照と設定はいいけど、演算(加減算)は駄目ってことでよいみたい。なるほどー。
2014-05-28 13:01:09@satoh_fumiyasu sig_atomic_tはリード・ライトしか保証してません。最初、0xCAFEBABEが入っていた変数に0xDEADBEAFを代入しようとした時にシグナルハンドラに処理が移っても0xDEADBABEのような中間値が見えないことを保証しているだけです
2014-05-28 13:05:47@n_soda @koie なるほど、tnozaki さんのツイートで atomic.h は調べた記憶。apt-file search /atomic.h →それっぽいのはない…。orz stdatomic.h は C11 かー。へぇ。
2014-05-28 13:06:11@satoh_fumiyasu @koie SolarisやNetBSDにはあるんですけどね。ただし、APIは微妙に違います(ぉ
2014-05-28 13:08:35