bigstack.c

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|