リエントラントについて調べてて、以下のWikipediaのリエントラントでもスレッドセーフでもないソースコード例と、その改善例が紹介されてました。
https://ja.wikipedia.org/wiki/リエントラント
次の例の swap() 関数は、リエントラントではない(同時にスレッドセーフでもない)。したがってこれを割り込みサービスルーチン isr() で使用すべきでない。
int t; void swap(int *x, int *y) { t = *x; *x = *y; // ここでハード割り込みが起きて isr() が呼び出される可能性がある。 *y = t; } void isr() { int x = 1, y = 2; swap(&x, &y); }
次のswap関数はリエントラントかつスレッドセーフである。
void swap(int *x, int *y) { int t; t = *x; *x = *y; // ここでハード割り込みが起きて isr() が呼び出される可能性がある。 *y = t; } void isr() { int x = 1, y = 2; swap(&x, &y); }
確かに最初の例は変数t
がグローバル変数であり他の箇所で書き換えられてしまう可能性がありリエントラント性が阻害されてしまう、ということは分かるのですが、最初の例のコメントの箇所で割り込みが起きて isr()
がコールされたとしても、上記の例だとその結果(swap()
後のx
とy
の値)は改善例の結果と変わらないですよね?
そのため例としてしっくり来ず、もしかしたら自分の理解が間違っているのかと思って確認したい次第です。
上段の例では,
まずグローバル変数t
が静的領域に0で初期化され、
main()からirs()
がコールされたとして、
ローカル変数x
とy
がスタック領域にそれぞれ1と2で初期化れさて積まれて、
swap()
がコールされ、
t
にx
を代入、x
にy
を代入(この時点でt
の値は"1"、x
の値は"2")、
と、ここでハード割り込みによってirs()
がコールされ
新たにローカル変数x
とy
がスタック領域にそれぞれ1と2で初期化されて積まれて、
swap()
がコールされ、
t
にx
を代入、x
にy
を代入、y
にt
を代入(この時点でt
の値は"1"、x
の値は"2"、y
の値は"1")。

回答3件
あなたの回答
tips
プレビュー