/*	
 *	clipbmgc.h
 *
 *	Bitmap GC
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2014 Naoyuki Sawa
 *
 *	* Fri Dec 12 00:29:38 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	* Fri Dec 12 21:20:33 JST 2014 Naoyuki Sawa
 *	- gc_scan()をアセンブラ化しました。
 *	  当モジュールの機能とは直接関係有りませんが、gc_scan()は【スタックフレームを1命令で開放する工夫】の適用例にもなっています。
 *	- gc_mark()をアセンブラ化しました。
 *	- 以上のアセンブラ化を行った後、既存の「P/ECE用ガーベージコレクター」との速度比較を行って見ました。
 *	  Tclインタプリタで速度比較したところ、clipgc.cよりもclipbmgc.cの方が、約27%高速になりました。
 *	  今後は、極端にメモリ節約が必要なアプリケーションを除き、「Bitmap GC」を使用する方が良さそうです。
 *	* Sat Dec 13 11:52:53 JST 2014 Naoyuki Sawa
 *	- これまで、GC構造体にSRAM範囲を保持していましたが、ヒープ範囲を保持するように変更しました。
 *	  よく考えたら、GCのマーク対象は、SRAM全体ではなく、ヒープ範囲だけで良いことに気付いたからです。
 *	  (pceHeapAlloc()によって、メモリブロックが割り当てられる範囲は、ヒープ範囲だけだからです。)
 *	  上記のように変更することによって、Bitmapのサイズも減らす事ができるメリットも得られました。
 *	- 上記の変更は、既存の'clipgc.c'にも適用可能なのですが、'clipgc.c'には適用しないことにしました。
 *	  'clipgc.c'はこれまで長い間使用して来たので、今、大きな変更をするのは少し怖いと思ったからです。
 *	* Sat Dec 13 13:46:03 JST 2014 Naoyuki Sawa
 *	- 「Bitmap単位をまたぐメモリブロックの、後半のBitmap単位内のアドレスを参照するポインタが有っても、メモリブロックを開放してしまうバグ」を修正しました。
 *	  これまでは上記のバグのために、意図せず'積極的な'GCの挙動となってしまっていました。
 *	  今回上記のバグを修正したので、意図通り'保守的な'GCの挙動となりました。
 *	* Sun Dec 14 01:27:04 JST 2014 Naoyuki Sawa
 *	- 以下二点の変更を行い、高速化しました。
 *	- pceHeapAlloc()が、毎回ヒープ先頭から走査を行うのではなく、最後に割り当てたメモリブロックから走査を継続するようにしました。
 *	- pceHeapFree()は何もしないようにし、メモリ開放はBitmapGC_Run()に集約しました。
 *	  _gc.phmが指しているメモリブロックが開放されないようにするためです。
 *	* Mon Dec 15 21:12:11 JST 2014 Naoyuki Sawa
 *	- pceFileCreate(),pceFileDelete()を呼び出す前に、BitmapGC_Run()を行うようにしました。
 *	- pceFileCreate(),pceFileDelete()は、カーネル内でpceHeapAlloc()に静的リンクしています。
 *	  ヒープの残り容量が4KB未満のときに、上記のAPIを呼び出すと、BitmapGC_Run()が起動されず、APIが失敗します。
 *	  そこで、pceFileCreate(),pceFileDelete()を呼び出す前に、BitmapGC_Run()を行い、可能な限りヒープを空けることにしました。
 *	- 上記のAPIは、カーネル内でpceHeapFree()にも静的リンクしており、当モジュールによるpceHeapFree()の無効化の対象外となってしまいますが、問題有りません。
 *	  pceFileCreate(),pceFileDelete()は、APIの開始時に確保したメモリブロックを、APIの終了前に開放するからです。
 *	  アプリケーションから見れば、ヒープの状態は、pceFileCreate(),pceFileDelete()を呼び出す前と処理の後とで、変わりません。
 *	- 厳密には、pceFileCreate(),pceFileDelete()だけでなく、pceFileRename()とpceFileLoad()にも同様の対策が必要なのですが、今回は対策しないことにしました。
 *	  pceFileRename(),pceFileLoad()は、アプリケーションから利用しないと判断したからです。
 *	  判断理由については、clippce.cの「ヒープマネージャAPIの排他制御」の、'{{2014/09/05追記:'のコメントを参照してください。
 *	* Fri Dec 19 22:30:18 JST 2014 Naoyuki Sawa
 *	- _gc_run(),new_pceHeapAlloc(),new_pceFileCreate(),new_pceFileDelete()の排他制御を、ENTER_CS/LEAVE_CS⇒ENTER_IL(1)/LEAVE_ILに変更しました。
 */
#ifndef __CLIP_BMGC_H__
#define __CLIP_BMGC_H__

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

/* Bitmap GCを初期化します。
 * [in]
 *	unit		Bitmap単位
 * [note]
 *	* BitmapGC_Init()を呼ぶと、pceHeapAlloc()がBitmap GC対応となります。
 *	* BitmapGC_Init()を呼んだアプリケーションは、終了前に必ずBitmapGC_Free()を呼んでください。
 *	  BitmapGC_Free()を呼ばずに終了すると、P/ECEがハングアップします。
 *	* unitは、Bitmapの1ビットで、メモリ何バイト分への参照を管理するかを表します。(1ビット当り(1<<unit)[byte]に相当する)
 *	  unitに大きな値を指定するほどBitmapのサイズを節約できますが、実際には参照されていないメモリプロックを参照されていると判断して開放できない頻度が高くなります。
 *	- unitに指定できる範囲は、2〜8です。
 *	  下限を2とした理由は、P/ECEのメモリアロケータがワード単位であり、ワードサイズ未満の参照を管理することは無意味だからです。
 *	  上限を8とした理由は、Asm版を実装する時に、一命令でシフトできるようにするためです。
 *	- 実際のアプリケーションで、unitの値をを幾つにするのが適切かをまだ検証していないのですが、おそらく2〜5ぐらいだと思います。
 *	  ↓2014/12/12追記
 *	  Tclインタプリタで試して見ました。2と3がほぼ同じですが3の方が僅かに高速でした。4以上は大きくなるほど目に見えて速度低下しました。
 *	  おそらく、4以上にすると保守性のために開放できないメモリが増えて、メモリアロケーションに時間がかかるようになるからだと思います。
 *	  【結論】特にメモリ節約する必要が無い限り、3(or2)を指定するのが良いと思います。
 */
void BitmapGC_Init(int unit);	//unit=2〜8	推奨値=3(上記参照)

/* Bitmap GCを解除します。
 * [note]
 *	* Bitmap GCが初期化されていなかった場合は、何もしません。
 */
void BitmapGC_Free();

/* 直ちにBitmap GCを起動します。
 * [note]
 *	* 通常は、pceHeapAlloc()の中で自動的にBitmap GCが起動します。
 *	  アプリケーションプログラムが明示的にBitmap GCを起動する必要はありません。
 *	- 処理時間に余裕のある時にBitmapGC_Run()を呼んで明示的にBitmap GCを起動し、
 *	  その後の処理時間を節約するのが、この関数の利用法です。
 */
void BitmapGC_Run();

#endif//__CLIP_BMGC_H__
