C:\home\SVGCats_src\src\bigstack.c
1|/************************************************************************** 2|* 1. <<< 大きいスタック (BigStack) >>> 3|* 4|*・ローカルスタック(ローカル変数に割り当てられるスタック領域)とは別に、 5|* 大きいメモリ領域を必要とする場合のスタックです。 6|*・このスタック領域は、グローバル変数の領域に取られます。 7|*・BigStack_max 変数に、最大の使用メモリサイズが格納されます。 8|* ただし、BIGSTACK_CHKSIZE を設定してください。 9|* 10|*【内部補足】 11|* --- スタックの構造 --- 12|*・BigStack のスタックは、スタック・ブロックが繰り返し入っている。 13|*・BigStack は、スタック・ブロックを単位としてスタックを開放する。 14|*・スタック・ブロックは、次のような構造になっている。 15|* [1つ前のスタック・ブロックの先頭アドレス][スタック領域] 16|* ↓次の図は無くしてしまいました (^^; 17|* <IMG src="bigstac1.gif"> 18|* 19|*・1.BigStack_start 関数で、1つ前のスタック・ブロックの先頭アドレスを記録して、 20|* 現在のスタック・ポインタの位置をメンバ変数に取っておき、 スタック・ポイ 21|* ンタをスタック領域に移動する。 22|*・2.BigStack_alloc 関数で、スタック領域をユーザのために確保して、 スタック・ 23|* ポインタを進める。 24|*・3.BigStack_end 関数で、メンバ変数に取っておいた値を用いて、 スタック・ 25|* ポインタを現在のスタック・ブロックの先頭に移動し、 その位置に記録してある 26|* 「1つ前のスタック・ブロックの先頭アドレス」を メンバ変数に取っておく。 27|* 28|*・最初のスタック・ブロックの「1つ前のスタック・ブロックの先頭アドレス」は、 29|* NULL が入る。 30|***************************************************************************/ 31| 32|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 33|// #pragma hdrstop ("mixer_precomp") 34| 35|#define STDLIBS_INCLUDE 36|#define STDLIBS_INCLUDE_STDIO_H 37|#define STDLIBS_INCLUDE_STDLIB_H 38| 39|#if defined(USES_MXP_AUTOINC) 40| #include "bigstack.ah" /* Auto include header, Look at mixer-... folder */ 41|#endif 42| 43|#ifdef count 44|#undef count 45|#endif 46|#ifdef sp 47|#undef sp 48|#endif 49| 50| 51|/*---------------------------------------------------------------------*/ 52|/* 2. <<<◆ ビッグスタック・システム >>> */ 53|/*---------------------------------------------------------------------*/ 54| 55|BigStack BigStack_Sys_arrX; /* デフォルト */ 56| 57|#ifdef USES_MULTASK 58|BigStack* BigStack_Sys_arr = &BigStack_Sys_arrX; /* 配列 */ 59|int BigStack_Sys_mArr = 1; 60|#endif 61| 62| 63| 64| 65|/************************************************************************** 66|* 3. <<< [BigStack_Sys_init] BisStack システムを初期化する >>> 67|*【引数】 68|* ・BigStack* works; ワーク領域の先頭アドレス 69|* ・int mWork; 配列 work の最大要素数 70|*【補足】 71|*・シングルタスクでは呼び出す必要はありません。 72|*・本関数を呼び出す前に、MulTask_Sys_init を呼び出してください。 73|***************************************************************************/ 74|#ifdef USES_MULTASK 75|void BigStack_Sys_init( BigStack* works, int mWork ) 76|{ 77| ASSERT( MulTask_Sys_isEnable() ); 78| 79| BigStack_Sys_arr = works; 80| BigStack_Sys_mArr = mWork; 81|} 82|#endif 83| 84| 85| 86|/*---------------------------------------------------------------------*/ 87|/* 4. <<<◆ ビッグスタック領域 >>> */ 88|/*---------------------------------------------------------------------*/ 89| 90| 91| 92| 93| 94|/************************************************************************** 95|* 5. <<< [BigStack_init_imp] 初期化する >>> 96|*【引数】 97|* ・char* mem; 大きいスタック領域の先頭アドレス 98|* ・size_t mem_sizeof; mem のメモリサイズ(バイト) 99|*【補足】 100|*・BigStack_init マクロから呼ばれます。 101|*・マルチタスク・システムでは、MulTask_Sys_init 関数を呼び出してから 102|* BigStack_init マクロを実行してください。 103|***************************************************************************/ 104|void BigStack_init_imp( BigStack* m, char* mem, size_t mem_sizeof ) 105|{ 106| ERRORS_INITCHK( m, 0 ); 107| ASSERT( ((int)mem & 3) == 0 ); /* ポインタも格納するため */ 108| 109| m->mem = mem; 110| m->size = mem_sizeof; 111| m->sp = mem; 112| m->block1 = NULL; 113|} 114| 115| 116| 117|/************************************************************************** 118|* 6. <<< [BigStack_start_imp] スタックブロックの開始の指示 >>> 119|***************************************************************************/ 120|void BigStack_start_imp( BigStack* m ) 121|{ 122| ERRORS_INITCHK( m, 1 ); 123| 124| #ifndef NDEBUG 125| m->count ++; 126| #endif 127| 128| /* BigStack_block1 を mem 上に待避 */ 129| *(char**)m->sp = m->block1; 130| 131| /* スタックブロックの区切りのメモリ位置を記録 */ 132| m->block1 = m->sp; 133| 134| m->sp += sizeof( char* ); 135|} 136| 137| 138| 139|/************************************************************************** 140|* 7. <<< [BigStack_alloc_imp] スタックからメモリ領域を確保する >>> 141|*【補足】 142|*・char* 型以外のメモリ領域として使う場合は、キャストしてください。 143|*【内部補足】 144|*・void* 型を返してもキャストは必要です。 145|***************************************************************************/ 146|char* BigStack_alloc_imp( BigStack* m, unsigned int size ) 147|{ 148| char* ret = m->sp; 149| 150| ERRORS_INITCHK( m, 2 ); 151| 152| #ifdef FOR_32BIT 153| size = ( (size + 3) & 0xFFFFFFFC ); /* 4の倍数に切上げ */ 154| #else 155| size = ( (size + 3) & 0xFFFC ); /* 4の倍数に切上げ */ 156| #endif 157| 158| if ( (m->sp - m->mem) + size > m->size ) { 159| error2_2( BigStack_Full, "BigStack 不足です (usable=%d, request=%d)", 160| m->size - (m->sp - m->mem), size ); 161| } 162| 163| m->sp += size; 164| 165| #ifdef BIGSTACK_CHKSIZE 166| if ( m->sp > m->mem + m->max ) { 167| m->max = m->sp - m->mem; 168| } 169| #endif 170| 171| return ret; 172|} 173| 174| 175| 176|/************************************************************************** 177|* 8. <<< [BigStack_end_imp] スタックブロックの終了の指示 >>> 178|***************************************************************************/ 179|void BigStack_end_imp( BigStack* m ) 180|{ 181| #ifndef NDEBUG 182| m->count --; 183| #endif 184| ERRORS_INITCHK( m, 1 ); 185| ASSERT( m->block1 != NULL ); /* 2重エラーの1度目でブレークすればヒントになります */ 186| 187| /* スタックポインタ sp を戻す */ 188| m->sp = m->block1; 189| 190| /* m->block1 を戻す */ 191| m->block1 = *(char**)m->sp; 192|} 193| 194| 195| 196|/************************************************************************** 197|* 9. <<< [BigStack_print_imp] デバッグ表示 >>> 198|***************************************************************************/ 199|#ifndef ERRORS_CUT_DEBUG_TOOL 200|void BigStack_print_imp( BigStack* m ) 201|{ 202| Errors_printf( "BigStack: mem=%p, size=0x%X, sp=%p, block1=%p", 203| m->mem, m->size, m->sp, m->block1 ); 204| #ifdef BIGSTACK_CHKSIZE 205| Errors_printf( "BigStack: max=0x%X", m->max ); 206| #endif 207| #ifndef NDEBUG 208| Errors_printf( "BigStack: count=%d", m->count ); 209| #endif 210|} 211|#endif 212| 213| 214|