Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

TortoiseSVN 1.6.3のTSVNCacheが重い

タグ: C++

どうも最近、Windows起動後にTSVNCacheがCPUリソースを100%使っている期間が昔(とても重かった時代のTortoiseSVN)みたいに長くなってるなぁと思ったら、

RE: TSVNCache slowness after upgrading to 1.6.3.16613

> Previously I was using 1.6.1 and upgraded to 1.6.3.16613 some days ago.
>
> Since then, *any* folder on Windows Explorer will take a long time to
> show up and during this time TSVNCache.exe uses 100% of one CPU [snip]

There have been several TSVNCache bugs discussed here and fixed in the latest nightly builds, ready for the next formal release of TortoiseSVN.

TortoiseSVN 1.6.3のバグだった。

RE: Re: High CPU usage caused by TSVNCache.exe at startup

I think I can see a problem in the source. Specifically, a test of the form

GetTickCount() - DRIVETYPETIMEOUT > drivetypeticker

is wrong for DRIVETYPETIMEOUT milliseconds after system start-up, and again every 49.7 days or so. But re-ordering as

GetTickCount() - drivetypeticker > DRIVETYPETIMEOUT

works better, provided the measured interval never exceeds 49.7 days.

GetTickCount()の戻り値型は「DWORD(unsigned long)」。
DRIVETYPETIMEOUTは「整数リテラル」で「300000」。
drivetypetickerは「DWORD型」で初期値「0」。

仮にGetTickCount()の戻り値が60000(起動1分)だとすると、上の式は次のように展開、評価される。

60000UL - 300000 > 0UL

通常の算術変換により、減算式の両項とその結果の型はunsigned longとなる。

(unsigned long)(60000UL - 300000UL) > 0UL
             (unsigned long)-240000 > 0UL

-240000はunsigned longで表現できない値なので、表現できる最大値より1大きい数を法とした剰余を演算結果とする。
(ただしC言語系の%演算では剰余も負数になるので、ここでは新しい型で表現しうる最大の数に1加えた数を加えることにする)

(unsigned long)(-240000 + ULONG_MAX + 1) > 0UL
                            4294727296UL > 0UL

「-240000 > 0」でfalseとなるはずのところが、「4294727296 > 0」でtrueになってしまった。
このように、上の式では、GetTickCount()が300000以上を返すようになる(起動後5分以上経過する……ちょうどTSVNCacheが落ち着く頃合だ)まで正しい評価を行うことができない。

符合なし整数型でこのような評価を行う場合、「閾値で引いて基準値と比較する」のではなく、「基準値で引いて閾値と比較する」ようにしなければならない。

60000UL - 0UL > 300000
      60000UL > 300000UL

起動から49.7日が経過するとGetTickCount()は0に戻るが、その場合でもこの式の評価は大概正しい。

                          0UL - 4294727296UL > 300000
                  (unsigned long)-4294727296 > 300000
(unsigned long)(-4294727296 + ULONG_MAX + 1) > 300000
                                    240000UL > 300000UL

この辺、符号なし変数型の「面白い」ところであり、「けどむしろ間違いの元になることの方が多いから嫌」なところである。

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/212-773414f6
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。