tarosukeの日記: [wOS] まーたビョーキが始まった。 9
日記 by
tarosuke
参照カウンタが0になろうとしている時に同時に参照をコピー(カウンタはインクリメント)しようとしている場合、いくら参照カウンタの動作がアトミックであろうと実体をdeleteしたあとに参照カウンタがインクリメントされ、すでにdeleteされた実体へのポインタがコピーされてしまう問題が未解決だ。
世の中にあるSMPで参照カウンタ使ってるブツはこれを解決してるんだろうけどそれっぽいのは探せなかった。というかこれがあるから無駄がクソ多くても下手に扱ってメモリリークすることになってもガーベジコレクションするのかも知れんがな。
...さてwOSではどうしようか。GCは特にCやC++みたいにメモリを丸裸に近い状態で扱う言語でやるのはキショいのでボツとして、あるいはタスク同様墓場に放り込んで実際の削除を遅延させて再確認するか?それとも実際には参照を保持して使うのは各々のプロセスなのでスレッドをサポートしないwOSにおいては参照の破棄と参照のコピーが同時に発生することはあり得ないからそのままでよしとするという方向もある...。
...明後日が大変になるからとりあえず寝よう。と、問題が放置されてきたわけだがw
通りすがりですが (スコア:2)
案1)
参照をつくる時点でカウンタを+1する
(参照中=使用中)
案2)
コピーする前にカウンタを+1 してコピーが終わったら-1 する
(コピー中=参照中=使用中)
とかで解決しませんか?外していたらごめんなさい.
Re:通りすがりですが (スコア:1)
えーと、コピーする前に実体をdeleteする事が確定しちゃっててコピー側で何をやってもdeleteされちゃうんだけど、コピー側は何も知らずに参照をコピーして使っちゃうのが問題なのです。
これは排他処理してもダメなのですねー。コピー側のインクリメントが先だと問題ないのですが、delete側が先に判定しちゃうとどうしようもないです。
あるいはゼロ判定とインクリメントをアトミックに処理してコピー失敗とかすれば...とも思わないでもないですが、その時はすでにdeleteされたメモリを参照することになります。
...排他処理してロック待ちがあったらdeleteしないって手もありそうですね。そう言えば。
今のロックだとロック待ちを認識できないのでそのままでは使えませんが。
Re:通りすがりですが (スコア:2)
>えーと、コピーする前に実体をdeleteする事が確定しちゃっててコピー側で何をやってもdeleteされちゃうんだけど、
その問題が起きる時点で何か妙な印象を受けます.
コピー側が参照を保持していて,実体へアクセスできる状態なのに,参照カウンタが0になってるんですか?
(参照カウンタが0になると実体を消去する,という前提で話をしています)
参照をコピーするときに参照カウンタを+1する処理が抜けていませんか?
Re:通りすがりですが (スコア:2)
それはSMPってところを考慮してないですよね?
Re:通りすがりですが (スコア:1)
ちょっと前までそう思ってて放置してた問題でもあるんですが、SMPではそうは行かないんですね。
wOSでは参照持ってるも使うのも各プロセスだけでスレッドはないのでそこは問題ないんですが、一般的な参照カウンタ式の実体管理だとまずいです。
また、参照を自動変数で保持している限りコピーはコピー元のスコープ内でのみ起きるのでその場合も大丈夫です。
同一コンテキストを同時に複数のプロセッサが走ることはありえませんから。
なのでこれはSMPで参照が複数のコンテキストで共有されるメモリスコープにある場合のみの問題です。
それよりも (スコア:2)
参照カウンタをretainしようと思ったら、参照カウンタを置いてあるメモリが無かったってござるっていう問題が起こりそう。
Re:それよりも (スコア:1)
そう言えばそうですねー。いきなりdelete済メモリをインクリメントすることになりそう。
遅延が妥当かな (スコア:1)
現実解としては遅延が一番妥当だと思う。
どうやって遅延するかによってはガベコレと変わらないことになるかもだけど。
スレッドなしに加えてプロセス間メモリ共有も無いなら漢解決もありとは思うけど、
そこ割りきっちゃうと、後でいぢるときに制約がきつくなりそうな気がする。
Re:遅延が妥当かな (スコア:1)
プロセス間メモリ共有はあるけどそこを介して参照が渡ることはないので漢解決もおkなのです。
あるいは参照ではなくプロセスの間通信路として作り込んでしまうというもっと漢な解決法も...そしたらコピーも発生しないし...参照やめやめ(ぉ