Chinaunix首页 | 论坛 | 博客
  • 博客访问: 291941
  • 博文数量: 134
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 770
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-08 15:19
文章分类

全部博文(134)

文章存档

2012年(134)

分类:

2012-04-08 16:38:16

原文地址:实现的内存管理器 作者:jmy2446267


  1. #if 0
  2. 在设计的过程中常忘记写返回值,导致常常出问题
  3. 还有一种是RETURN_VAL_IF_FAIL,这种是有异常的时候才返回
  4. 所以,需要在后面添上正常情况的返回值,这里很容易漏掉
  5. #endif
  6. #include "c.h"
  7. #include "memmgr2.h"


  8. #define DISABLE_D
  9. #define DISABLE_MSG

  10. #define DEBUG0
  11. #include "debug.h"

  12. #define Memory_Size_512K            (1<<19)
  13. #define Memory_Size_1M                (1<<20)
  14. #define Memory_Size_4M                (1<<22)
  15. #define Global_Pool_Size             Memory_Size_1M
  16. #define Min_Data_Size                 4

  17. #define Max_Chain_Array_Length         15

  18. #define Max_Large_Size                Memory_Size_4M
  19. #define Max_Chain_Block_Size         Memory_Size_512K
  20. #define Min_Chain_Block_Size 32


  21. #define Pointer_In_Zone(ptr,left,right)    \
  22.     ((char*)(ptr)-(char*)(left)>=0 && (char*)(ptr)-(char*)(right)<=0)
  23.     
  24. struct descriptor {
  25.     const char *file;
  26.     const char *func;
  27.      int         line;
  28.      int         size;
  29.     struct descriptor *next;
  30. };

  31. struct memory_pool {
  32.     char        *end;
  33.     char         *last;
  34.     int         failed;
  35.     struct memory_pool *current;
  36.     struct memory_pool *next;
  37. };

  38. struct memory_chain {
  39.     struct descriptor *deactive;
  40.     struct descriptor *active;
  41.     int     block_size;
  42. };

  43. static struct memory_manager {
  44.     struct     memory_pool *pool;
  45.     struct     descriptor     *large;
  46.     int     max_block_size;
  47.     
  48.     int large_count;
  49.     int pool_count;
  50.     
  51.     int allocate_from_large_stamp;
  52.     int allocate_from_pool_stamp;
  53.     int     allocate_from_chain_stamp;
  54.     
  55.     long long     allocate_memory_stamp;//pool+large
  56.     long long allocate_data_stamp;//memory_new size sum
  57.     double         ratio;
  58.     struct memory_chain chain[Max_Chain_Array_Length];
  59. }g_mmgr;

  60. //暂时不考虑内存对齐的问题
  61. union align {
  62.     int i;
  63.     long l;
  64.     long *lp;
  65.     void *p;
  66.     void (*fp)(void);
  67.     float f;
  68.     double d;
  69.     long double ld;
  70. };

  71. static struct memory_pool *alloc_memory_pool(void);
  72. ///////////////////////////////////////////////////////////////////////////////////
  73. ///////////////////////////////////////////////////////////////////////////////////
  74. static inline void inc_alloc_memory_stamp(int size)
  75. {
  76.     return_if_fail(size>=Min_Data_Size);
  77.     g_mmgr.allocate_memory_stamp += size;
  78.     if(g_mmgr.allocate_memory_stamp)
  79.     g_mmgr.ratio=1.0*g_mmgr.allocate_data_stamp/g_mmgr.allocate_memory_stamp;
  80. }

  81. static inline void inc_alloc_data_stamp(int size)
  82. {
  83.     return_if_fail(size>=Min_Data_Size);
  84.     g_mmgr.allocate_data_stamp += size;
  85.     if(g_mmgr.allocate_memory_stamp)
  86.     g_mmgr.ratio=1.0*g_mmgr.allocate_data_stamp/g_mmgr.allocate_memory_stamp;
  87. }

  88. #define Union_Align_Size             (sizeof(union align))
  89. #define Align_Size(size)             (Round_Up((size),Union_Align_Size))
  90. #define Desptr_Size                 (sizeof(struct descriptor))
  91. #define PDesptr_Size                (sizeof(struct descriptor*))
  92. #define Data_Package_Size(size)     (Align_Size(size)+Desptr_Size)
  93. #define Desptr_Package_Size(desptr)    (Data_Package_Size(desptr->size))
  94. #define Min_Package_Size             (Data_Package_Size(Min_Data_Size))
  95. #define Data_Addr_of_Pool(pool)     (char*)((char*)pool+sizeof *(pool))
  96. #define Pool_End(pool)                (char*)((char*)(pool)+Global_Pool_Size)


  97. //保证是对齐后的
  98. void *sys_new(int size)
  99. {
  100.     return_val_if_fail(size >= Min_Data_Size,0);
  101.     void *ptr=calloc(1,size);
  102.     return_val_if_fail(ptr!=0 , 0);
  103.     inc_alloc_memory_stamp(size);
  104.     return ptr;
  105. }

  106. void sys_free(void *ptr)
  107. {
  108.     return_if_fail(ptr!=0);
  109.     if(ptr != 0)free(ptr);
  110. }

  111. static int init_memory_manager(void)
  112. {
  113.     Zero_Memory(&g_mmgr);
  114.     struct memory_pool *pool=alloc_memory_pool();
  115.     return_val_if_fail(pool!=0 , -1);
  116.     int i;
  117.     int chain_block_size=Min_Chain_Block_Size;
  118.     struct memory_chain *chain=g_mmgr.chain;
  119.     for(i=0 ; i<Max_Chain_Array_Length ; i++){
  120.         chain[i].block_size=chain_block_size;
  121.         chain_block_size <<= 1;
  122.     }
  123.     return_val_if_fail(
  124.         chain[i-1].block_size <= Max_Chain_Block_Size , -1
  125.     );
  126.     g_mmgr.max_block_size=chain[i-1].block_size;
  127.     return 0;
  128. }

  129. //size has been aligned
  130. #define Enough_Space_for_Alloc(pool,size) \
  131.     ( (char*)((pool)->last + (size)) <= Pool_End(pool))

  132. #define Set_Desptr(desptr,_file,_func,_line,_size) do { \
  133.             desptr->file=_file;\
  134.             desptr->func=_func;\
  135.             desptr->line=_line;\
  136.             desptr->size=_size;\
  137.         } while(0)

  138. #define Ptr_Entry_Desptr(ptr)         ((struct descriptor*)((char*)(ptr)-Desptr_Size))
  139. #define Desptr_Entry_Ptr(desptr)     ((char*)((char*)(desptr)+sizeof *(desptr)))

  140. #define Show_Desptr(message,desptr)    do { \
  141.         msg(stdout,"\n%s\n",message);\
  142.         Show_Value(desptr->file,s);\
  143.         Show_Value(desptr->func,s);\
  144.         Show_Value(desptr->line,d);\
  145.         Show_Value(desptr->size,d);\
  146.     }while(0)
  147.     
  148. ///////////////////////////////////////////////////////////////////////////////////
  149. ///////////////////////////////////////////////////////////////////////////////////
  150. typedef int (*compare_func)(void *data,void *val);
  151. typedef void **(*entry_next_func)(void *data);

  152. int default_compare(void *data,void *val)
  153. {
  154.     return (int)((char*)data-(char*)val);
  155. }

  156. static void ** search_slist(
  157.     void **head,
  158.     int (*compare)(void *data,void *val),
  159.     void **(*entry_next)(void *data),
  160.     void *val
  161. )
  162. {
  163.     void **pp = 0;
  164.     for(pp = head; pp && *pp; pp = entry_next(*pp))
  165.         if(compare(*pp,val) == 0) break;
  166.     return pp;
  167. }

  168. static inline struct memory_pool **entry_next_pool(struct memory_pool *pool)
  169. {
  170.     return pool ? &pool->next : 0;
  171. }

  172. static inline struct descriptor **entry_next_desptr(struct descriptor *desptr)
  173. {
  174.     return desptr ? &desptr->next : 0;
  175. }

  176. static int compare_pool_for_enough_space(
  177.     struct memory_pool *pool , int size_package)
  178. {
  179.     if(Enough_Space_for_Alloc(pool,size_package)) return 0;
  180.     if(pool->failed++>4) pool->current = pool->next;
  181.     return -1;
  182. }

  183. static struct memory_pool *search_pool_for_enough_space(int size_package)
  184. {
  185.     return_val_if_fail(
  186.         size_package >= Min_Package_Size
  187.      && size_package <= g_mmgr.max_block_size,
  188.         0,
  189.         "Allocate Size Not In Normal Range , "
  190.         "%d out of [ %d , %d ]",
  191.         size_package , Min_Package_Size ,
  192.         g_mmgr.max_block_size
  193.     );
  194.     void **pp = search_slist(
  195.         (void            **    )&g_mmgr.pool->current,
  196.         (compare_func        )compare_pool_for_enough_space,
  197.         (entry_next_func    )entry_next_pool,
  198.         (void            *    )size_package
  199.     ) ;
  200.     return *(struct memory_pool **)pp ;
  201. }

  202. static int compare_pool_for_desptr(struct memory_pool *pool,
  203.                                     struct descriptor *desptr)
  204. {
  205.     void *left = Data_Addr_of_Pool(pool);
  206.     void *right = pool->last-Min_Package_Size;
  207.     if(Pointer_In_Zone(desptr,left, right)) return 0;
  208.     return -1;
  209. }

  210. static struct memory_pool *search_pool_for_desptr(struct descriptor *desptr)
  211. {
  212.     return_val_if_fail(desptr != 0 , 0);
  213.     void **pp = search_slist(
  214.         (void            **    )&g_mmgr.pool,
  215.         (compare_func        )compare_pool_for_desptr,
  216.         (entry_next_func    )entry_next_desptr,
  217.         (void            *    )desptr
  218.     );
  219.     return *(struct memory_pool **)pp;
  220. }

  221. static struct descriptor **search_large_for_desptr(struct descriptor *desptr)
  222. {
  223.     return_val_if_fail(desptr != 0, 0);
  224.     void **pp = search_slist(
  225.         (void            **    )&g_mmgr.large,
  226.         (compare_func        )default_compare,
  227.         (entry_next_func    )entry_next_desptr,
  228.         (void            *    )desptr
  229.     );
  230.     return (struct descriptor**)pp;
  231. }

  232. static struct memory_chain *search_chain_for_data_size(int size_data)
  233. {
  234.     int size_package=Data_Package_Size(size_data);
  235.     return_val_if_fail(
  236.         size_package >= Min_Package_Size
  237.      && size_package <= g_mmgr.max_block_size,
  238.         0,
  239.         "There is no Chain for Such Data Package Size"
  240.         " , %d out of [ %d , %d ]",
  241.         size_package , Min_Package_Size , g_mmgr.max_block_size
  242.     );
  243.     struct memory_chain *chain=g_mmgr.chain;
  244.     int i;
  245.     for(i=0 ; i < Max_Chain_Array_Length ; i++){
  246.         if(chain[i].block_size >= size_package)
  247.             return &chain[i];
  248.     }
  249.     return 0;
  250. }

  251. static struct memory_chain *search_chain_for_desptr(struct descriptor *desptr)
  252. {
  253.     return desptr ? search_chain_for_data_size(desptr->size) : 0;
  254. }

  255. static struct descriptor **search_active_for_desptr(
  256.     struct memory_chain *chain , struct descriptor *desptr)
  257. {
  258.     return_val_if_fail(chain != 0 , 0);
  259.     return_val_if_fail(desptr != 0 , 0);
  260.     
  261.     void **pp = search_slist(
  262.         (void **    )        &chain->active,
  263.         (compare_func    )        default_compare,
  264.         (entry_next_func)        entry_next_desptr,
  265.         (void        *    )        desptr
  266.     );
  267.     return (struct descriptor **)pp;
  268. }

  269. static struct descriptor **search_chain_active_for_desptr(struct descriptor *desptr)
  270. {
  271.     struct memory_chain *chain=search_chain_for_desptr(desptr);
  272.     return_val_if_fail(chain != 0 , 0);
  273.     return search_active_for_desptr(chain,desptr);
  274. }

  275. static struct descriptor **search_chain_deactive_for_desptr(struct descriptor *desptr)
  276. {
  277.     struct memory_chain *chain=search_chain_for_desptr(desptr);
  278.     return_val_if_fail(chain!=0 , 0);
  279.     void **pp = search_slist(
  280.         (void **    )        &chain->deactive,
  281.         (compare_func    )        default_compare,
  282.         (entry_next_func)        entry_next_desptr,
  283.         (void        *    )        desptr
  284.     );
  285.     return (struct descriptor **)pp;
  286. }
  287. ///////////////////////////////////////////////////////////////////////////////////
  288. ///////////////////////////////////////////////////////////////////////////////////
  289. static int desptr_add2_chain_active(struct descriptor *desptr)
  290. {
  291.     return_val_if_fail(desptr != 0 , -1);
  292.     struct memory_chain *chain=search_chain_for_desptr(desptr);
  293.     return_val_if_fail(chain != 0 , -1);
  294.     desptr->next = chain->active;
  295.     chain->active = desptr;
  296.     return 0;
  297. }

  298. #define Clear_Desptr(desptr,size)     Bzero(Desptr_Entry_Ptr(desptr),(size)-sizeof *(desptr))

  299. static int desptr_add2_chain_deactive(struct descriptor *desptr,struct memory_chain *chain)
  300. {
  301.     return_val_if_fail(desptr!=0,-1);
  302.     return_val_if_fail(chain!=0,-1);
  303.     Clear_Desptr(desptr,chain->block_size);
  304.     desptr->next=chain->deactive;
  305.     chain->deactive=desptr;
  306.     return 0;
  307. }

  308. static int desptr_add2_deactive(struct descriptor *desptr)
  309. {
  310.     return_val_if_fail(desptr!=0,-1);
  311.     struct memory_chain *chain=search_chain_for_desptr(desptr);
  312.     return_val_if_fail(chain!=0,-1);
  313.     return desptr_add2_chain_deactive(desptr,chain);
  314. }
  315. ///////////////////////////////////////////////////////////////////////////////////
  316. ///////////////////////////////////////////////////////////////////////////////////
  317. static struct memory_pool *alloc_memory_pool(void)
  318. {
  319.     struct memory_pool *pool=sys_new(Global_Pool_Size);
  320.     return_val_if_fail(pool!=0,0);
  321.     g_mmgr.pool_count++;
  322.     pool->last=Data_Addr_of_Pool(pool);
  323.     pool->end=Pool_End(pool);
  324.     pool->current=pool;
  325.     pool->failed=0;
  326.     pool->next=g_mmgr.pool;
  327.     g_mmgr.pool=pool;
  328.     return pool;
  329. }

  330. //数据大小,所以需要内部对其
  331. static void *alloc_from_large(int size_data,
  332.     const char *file , const char *func , const int line)
  333. {
  334.     return_val_if_fail(size_data >= Min_Data_Size,0);
  335.     int size_package = Data_Package_Size(size_data);
  336.     return_val_if_fail(
  337.         size_package > g_mmgr.max_block_size
  338.      &&    size_package <= Max_Large_Size,
  339.         0,
  340.         "Allocate Data Package Size Not In The Normal Range"
  341.         " , %d Out of [ %d , %d ] .",
  342.         size_package , g_mmgr.max_block_size , Max_Large_Size
  343.     );
  344.     struct descriptor *desptr=(struct descriptor*)sys_new(size_package);
  345.     return_val_if_fail(desptr!=0,0,"Allocate Large Memory Failed");
  346.     Set_Desptr(desptr,file,func,line,size_data);
  347.     desptr->next=g_mmgr.large;
  348.     g_mmgr.large=desptr;
  349.     g_mmgr.large_count++;
  350.     g_mmgr.allocate_from_large_stamp++;
  351.     inc_alloc_data_stamp(size_data);
  352.     return Desptr_Entry_Ptr(desptr);
  353.     /*
  354.     以下函数在sys_new中就自动设置了
  355.     int_alloc_memory_stamp(size_package);
  356.     */
  357. }

  358. #if 0
  359. 一个bug,在pool中申请内存时通常是因为chain deactive中没有,此时不能传入size_Data
  360. 给pool,应按size_data在chain中的block_size传,否则pool会按Data_Package_Size分,
  361. 造成分配过小,这样容易造成数据覆盖
  362. 注意分清size_data,size_package,size_block区别
  363. #endif
  364. //数据大小,内部对齐
  365. static void *alloc_from_pool(int size_data ,
  366.     const char *file , const char *func , int line)
  367. {
  368.     int size_package = Data_Package_Size(size_data);
  369.     struct memory_chain *chain=search_chain_for_data_size(size_data);
  370.     int size_block = chain->block_size;
  371.     return_val_if_fail(chain!=0,0,"Chain For Data Size Null");
  372.     return_val_if_fail(
  373.         size_package >= Min_Package_Size
  374.      &&    size_package <= g_mmgr.max_block_size,
  375.         0,
  376.         "Allocate Data Package Size Not In The Normal Range"
  377.         " , %d Out of [ %d , %d ] .",
  378.         size_package , Min_Package_Size , g_mmgr.max_block_size
  379.     );
  380.     struct memory_pool *pool=search_pool_for_enough_space(size_block);
  381.     if( pool == 0) pool = alloc_memory_pool();
  382.     return_val_if_fail(pool != 0 , 0);
  383.     return_val_if_fail(
  384.         Enough_Space_for_Alloc(pool,size_block),0);
  385.     struct descriptor *desptr = (struct descriptor*)pool->last;
  386.     pool->last += size_block;
  387.     return_val_if_fail(pool->last <= Pool_End(pool) , 0);
  388.     Set_Desptr(desptr,file,func,line,size_data);
  389.     int ret = desptr_add2_chain_active(desptr);
  390.     return_val_if_fail(ret == 0 , 0);
  391.     inc_alloc_data_stamp(size_data);
  392.     g_mmgr.allocate_from_pool_stamp++;
  393.     return Desptr_Entry_Ptr(desptr);
  394. }

  395. static void *alloc_from_chain_deactive(int size_data,
  396.     const char *file , const char *func , const int line)
  397. {
  398.     return_val_if_fail(size_data >= Min_Data_Size,0,
  399.         "Data Size %d Lower Than %d .", size_data , Min_Data_Size);
  400.     int size_package = Data_Package_Size(size_data);
  401.     return_val_if_fail(
  402.         size_package >= Min_Package_Size
  403.      &&    size_package <= g_mmgr.max_block_size,
  404.         0,
  405.         "Allocate Data Package Size Not In The Normal Range"
  406.         " , %d Out of [ %d , %d ] .",
  407.         size_package , Min_Package_Size , g_mmgr.max_block_size
  408.     );

  409.     struct memory_chain *chain=search_chain_for_data_size(size_data);
  410.     return_val_if_fail( chain!=0, 0 ,
  411.         "No Chain For Such Data Size %d ." , size_data);
  412.     struct descriptor *desptr=chain->deactive;
  413.     if(desptr == 0) return desptr;

  414.     chain->deactive=desptr->next;
  415.     Set_Desptr(desptr,file,func,line,size_data);
  416.     desptr_add2_chain_active(desptr);

  417.     g_mmgr.allocate_from_chain_stamp++;
  418.     inc_alloc_data_stamp(size_data);

  419.     return Desptr_Entry_Ptr(desptr);
  420. }

  421. void *memory_new(int size_data,
  422.     const char *file , const char *func , const int line)
  423. {
  424.     msg(stdout,"\nAllocate Memory :");
  425.     msg(stdout,"\n<< : In %s %s Line %d , Alloc Size = %d .",
  426.         file , func , line , size_data);
  427.     if(g_mmgr.pool==0 && g_mmgr.large==0)
  428.         init_memory_manager();    
  429.         
  430.     if(size_data < Min_Data_Size) {
  431.         msg(stdout,"\n>> : Failed , Data Size %d Lower Than %d",
  432.             size_data , Min_Data_Size );
  433.         return 0;
  434.     }
  435.         
  436.     int size_package = Data_Package_Size(size_data);
  437.     if( size_package < Min_Package_Size
  438.          ||    size_package > Max_Large_Size){
  439.         msg(stdout,"\n>> : Failed , Package Size Not Normal"
  440.         " , %d Out of [ %d , %d ] .",
  441.         size_package , Min_Package_Size , Max_Large_Size);
  442.         return 0;
  443.     }
  444.     void *ptr=0;
  445.     if(size_package > g_mmgr.max_block_size
  446.         && size_package <= Max_Large_Size ){
  447.         ptr=alloc_from_large(size_data,file,func,line);
  448.         msg(stdout,"\n>> : %s , From Large "
  449.                 ", Addr = %p , Pkg_Size = %d ." ,
  450.                 ptr ? "Succeed" : "Failed" , ptr , size_package );
  451.         return ptr;
  452.     }
  453.     
  454.     struct descriptor *desptr = 0 ;
  455.     struct memory_chain *chain = 0;
  456.     ptr=alloc_from_chain_deactive(size_data,file,func,line);
  457.     if(ptr != 0) {
  458.         desptr = Ptr_Entry_Desptr(ptr);
  459.         chain=search_chain_for_desptr(desptr);
  460.         if(chain == 0) {
  461.             msg(stdout,"\n>> : Failed , Allocate Process Exception .");
  462.             return 0;
  463.         }
  464.         msg(stdout,"\n>> : Succeed , From Chain "
  465.                 ", Addr = %p , Pkg_Size = %d / %d / %d ." ,
  466.                 ptr , desptr->size , size_package , chain->block_size );        
  467.         return ptr;
  468.     }
  469. D__
  470.     ptr=alloc_from_pool(size_data , file , func , line);
  471.     if(ptr != 0) {
  472.         desptr = Ptr_Entry_Desptr(ptr);
  473.         chain=search_chain_for_desptr(desptr);
  474.         if(chain == 0) {
  475.             msg(stdout,"\n>> : Failed , Allocate Process Exception .");
  476.             return 0;
  477.         }
  478.         msg(stdout,"\n>> : Succeed , From Pool "
  479.                 ", Addr = %p , Size = %d / %d / %d ." ,
  480.                 ptr , desptr->size , size_package , chain->block_size );
  481.         
  482.         return ptr;
  483.     }    
  484.     msg(stdout,"\n>> : Failed , Allocate Process Exception .");
  485.     return ptr;
  486. }
  487. ///////////////////////////////////////////////////////////////////////////////////
  488. ///////////////////////////////////////////////////////////////////////////////////
  489. static int memory_free_large( struct descriptor *desptr,
  490.     const char *file , const char *func , const int line)
  491. {
  492.     return_val_if_fail(desptr != 0 , -1);
  493.     #if 0
  494.     只有当在POOL中找不到时才会从Large中找,这时无法判定desptr是否是
  495.     合法内存,故不能随便引用desptr->size,可能导致异常
  496.     int size_package=Data_Package_Size(desptr->size);
  497.     return_if_fail(
  498.         size_package > g_mmgr.max_block_size,
  499.         -1,
  500.         "Desptr Not Large , Size Only %d",
  501.         desptr->size
  502.     );
  503.     #endif
  504.     struct descriptor **pp = search_large_for_desptr(desptr);
  505.     return_val_if_fail( pp && *pp==desptr , -1);
  506.     *pp = (*pp)->next ;
  507.     sys_free(desptr);
  508.     g_mmgr.large_count--;
  509.     return 0;
  510. }

  511. static int memory_free_chain_active(struct descriptor *desptr,
  512.     const char *file , const char *func , const int line)
  513. {
  514.     return_val_if_fail(desptr != 0 , -1);
  515.     struct descriptor **pp=search_chain_active_for_desptr(desptr);
  516.     return_val_if_fail( pp!=0 && *pp == desptr , -1);
  517.     *pp = (*pp)->next;
  518.     desptr_add2_deactive(desptr);
  519.     return 0;        
  520. }

  521. int memory_free(void *ptr ,
  522.     const char *file , const char *func , const int line)
  523. {
  524.     msg(stdout,"\nRelease Memory :");
  525.     msg(stdout,"\n<< : In %s %s Line %d , Ptr Addr = %p . ",
  526.         file , func , line , ptr);
  527.     if(g_mmgr.pool==0 && g_mmgr.large==0)
  528.         init_memory_manager();
  529.     
  530.     if(ptr==0) {
  531.         msg(stdout,"\n>> : Failed , Release Ptr is Null . ");
  532.         return -1;
  533.     }
  534.     struct descriptor *desptr = Ptr_Entry_Desptr(ptr);
  535.     struct memory_pool *pool = search_pool_for_desptr(desptr);
  536.     if(pool==0){
  537.         int ret=memory_free_large(desptr,file,func,line);
  538.         if(ret!=0){
  539.             msg(stdout,"\n>> : Failed , Addr = %p Not Exist .",ptr);
  540.             return -1;
  541.         }
  542.     /*
  543.         下面这句return 0极其重要,因为上面如果ret=0,那么断言不会出发,
  544.         就会向下执行,因为desptr在memory_free_large中已经释放了,所以
  545.         在调用下面的函数过程中会发生错误,下面memory_free_chain_active
  546.         后面也有一个return 0,一定要注意,这时RETURN_IF_FAIL类的断言很容易
  547.         出错的地方
  548.     */
  549.         msg(stdout,"\n>> : Succeed , From Large , System Works Pretty Well .");
  550.         return 0;
  551.     }
  552.     int ret=memory_free_chain_active(desptr,file,func,line);
  553.     if(ret!=0){
  554.         msg(stdout,"\n>> : Failed , Addr = %p Not Exist .",ptr);
  555.         return -1;
  556.     }
  557.     msg(stdout,"\n>> : Succeed , From Chain , System Works Pretty Well .");
  558.     return 0;
  559. }
  560. ///////////////////////////////////////////////////////////////////////////////////
  561. ///////////////////////////////////////////////////////////////////////////////////
  562. void *memory_resize(void *ptr , int size_data,
  563.     const char *file , const char *func , const int line)
  564. {
  565.     msg(stdout,"\nReallocate Memory :");
  566.     msg(stdout,"\n<< : In %s %s Line %d , "
  567.              "Addr = %p , New Size = %d . ",
  568.             file , func , line , ptr , size_data);
  569.     if(g_mmgr.pool==0 && g_mmgr.large==0)
  570.         init_memory_manager();
  571.     if(ptr==0) {
  572.         msg(stdout,"\n>> : Failed , Realloc Ptr is Null .");
  573.         return ptr;
  574.     }
  575.     if(size_data<Min_Data_Size) {
  576.         msg(stdout,"\n>> : Failed , Realloc Size_Data Lower Than Normal Range .");
  577.         return ptr;
  578.     }
  579.     struct descriptor *desptr=Ptr_Entry_Desptr(ptr);
  580.     struct memory_pool *pool=search_pool_for_desptr(desptr);
  581.     struct descriptor **pp_large=0;
  582.     struct descriptor **pp_chain=0;
  583.     int old_size=0;
  584.     int new_size=Data_Package_Size(size_data);
  585.     if(pool==0) {
  586. D__
  587.         pp_large = search_large_for_desptr(desptr);
  588.         if(*pp_large != desptr ) {
  589.             msg(stdout,"\n>> : Failed , Addr = %p Not Exist .", ptr);
  590.             return ptr;
  591.         }
  592.         old_size=Data_Package_Size(desptr->size);
  593.         if(old_size >= new_size) {
  594.             msg(stdout,"\n>> : Succeed , Ptr Not Changed , "
  595.             "Original Size = %d .", desptr->size );
  596.             return ptr;
  597.         }
  598.         *pp_large = (*pp_large)->next;
  599.     }
  600.     else {
  601. D__
  602.         struct memory_chain *chain=search_chain_for_desptr(desptr);
  603.         if(chain == 0) {
  604.             msg(stdout,"\n>> : Failed , Addr = %p Not Exist .",ptr);
  605.             return ptr;
  606.         }
  607. D__
  608.         pp_chain = search_active_for_desptr(chain,desptr);
  609.         if( pp_chain == 0 || *pp_chain != desptr ) {
  610.             msg(stdout,"\n>> : Failed , Addr = %p Not Exist .",ptr);
  611.             return ptr;
  612.         }
  613. D__
  614.         if(new_size <= chain->block_size) {
  615.             msg(stdout,"\n>> : Succeed , Ptr Not Changed Yet , "
  616.             "Chain Block Size = %d" , chain->block_size);
  617.             return ptr;
  618.         }
  619.         *pp_chain = (*pp_chain)->next;
  620.     }
  621.     void *new_ptr=memory_new(size_data,file,func,line);
  622.     struct descriptor *new_desptr = Ptr_Entry_Desptr(new_ptr);
  623. D__
  624.     Show_Value(new_desptr->size,d);
  625.     if(new_ptr == 0) {
  626.         msg(stdout,"\n>> : Failed , Reallocate Process Exception .");
  627.         return ptr;
  628.     }
  629. D__
  630.     memcpy(new_ptr , ptr , Min(desptr->size , size_data));
  631.     new_desptr = Ptr_Entry_Desptr(new_ptr);
  632.     if(pp_large != 0) {
  633. D__
  634.         sys_free(desptr);
  635.         g_mmgr.large_count--;
  636.     }
  637.     else if(pp_chain != 0) {
  638. D__    
  639.         desptr_add2_deactive(desptr);
  640.     }    
  641.     new_desptr = Ptr_Entry_Desptr(new_ptr);
  642.     msg(stdout,"\n>> : Succeed , Ptr Addr = %p . "
  643.         "System Works Pretty Well ." , new_ptr);
  644.     return new_ptr;
  645. }

  646. const char *memory_status_string(void *ptr)
  647. {
  648.     return_val_if_fail(ptr!=0,0,"Ptr Null");
  649.     struct descriptor **pp;
  650.     struct descriptor *desptr = Ptr_Entry_Desptr(ptr);
  651. D__
  652.     struct memory_pool *pool=search_pool_for_desptr(desptr);
  653. D__
  654.     if(pool != 0) {
  655.         if((char*)desptr >= (char*)pool->last)
  656.             return "Memory_In_Pool";
  657. D__
  658.         pp=search_chain_active_for_desptr(desptr);
  659.         if(pp != 0 && *pp != 0) return "Memory_Allocated";
  660. D__
  661.         pp=search_chain_deactive_for_desptr(desptr);
  662.         if(pp != 0 && *pp != 0) return "Memory_Released";
  663.         
  664.         return "Memory_Invalid";
  665.     }
  666. D__
  667.     pp=search_large_for_desptr(desptr);
  668.     if(*pp) return "Memory_Allocated_In_Large";
  669.     return "Memory_Invalid";
  670. }

  671. static void memory_show_leaking(struct descriptor *desptr)
  672. {
  673.     if(desptr==0) return;
  674.     msg(stdout, "\n>> : %s %s Line %d , "
  675.         "Ptr Addr = %p , Size = %d . ",
  676.         desptr->file , desptr->func , desptr->line ,
  677.         Desptr_Entry_Ptr(desptr) , desptr->size);
  678. }

  679. void memory_leaking_check(void)
  680. {    
  681.     int flag=0;
  682.     struct descriptor *desptr=g_mmgr.large;
  683.     struct descriptor *next;
  684.     for( ; desptr!=0 ;desptr = next) {
  685.         if(flag==0){
  686.             msg(stdout,"\nMemory Leaking Danger :");
  687.             flag=1;
  688.         }
  689.         next = desptr->next;
  690.         memory_show_leaking(desptr);
  691.         sys_free(desptr);
  692.         g_mmgr.large_count--;
  693.     }
  694.     int i;
  695.     struct memory_chain *chain=g_mmgr.chain;
  696.     for(i=0 ; i<Max_Chain_Array_Length ; i++)
  697.         for( desptr=chain[i].active ; desptr ; desptr=desptr->next) {
  698.             if(flag==0){
  699.                 msg(stdout,"\nMemory Leaking Danger :");
  700.                 flag=1;
  701.             }
  702.             memory_show_leaking(desptr);
  703.         }
  704.     struct memory_pool *pool=g_mmgr.pool,*next_pool;
  705.     for( ; pool ; pool = next_pool ) {
  706.         next_pool=pool->next;
  707.         sys_free(pool);
  708.         g_mmgr.pool_count--;
  709.     }
  710.     if(g_mmgr.large_count != 0)
  711.         msg(stdout,"\n>> : Strange Exception Exist , Large Count None Zero");
  712.     if(g_mmgr.pool_count != 0)
  713.         msg(stdout,"\n>> : Strange Exception Exist , Pool Count None Zero");
  714.     Zero_Memory(&g_mmgr);
  715.     msg(stdout,"\n");
  716. }

  717. void memory_show()
  718. {
  719.     Show_Value(g_mmgr.large_count,d);
  720.     Show_Value(g_mmgr.pool_count,d);
  721.     Show_Value(g_mmgr.allocate_from_large_stamp,d);
  722.     Show_Value(g_mmgr.allocate_from_pool_stamp,d);
  723.     Show_Value(g_mmgr.allocate_from_chain_stamp,d);
  724.     Show_Value(g_mmgr.allocate_memory_stamp,lld);
  725.     Show_Value(g_mmgr.allocate_data_stamp,lld);
  726.     Show_Value(g_mmgr.ratio,lf);
  727. }

阅读(610) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~