mem1.c
上传用户:sunhongbo
上传日期:2022-01-25
资源大小:3010k
文件大小:7k
源码类别:

数据库系统

开发平台:

C/C++

  1. /*
  2. ** 2007 August 14
  3. **
  4. ** The author disclaims copyright to this source code.  In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. **    May you do good and not evil.
  8. **    May you find forgiveness for yourself and forgive others.
  9. **    May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. ** This file contains the C functions that implement a memory
  13. ** allocation subsystem for use by SQLite.  
  14. **
  15. ** $Id: mem1.c,v 1.17 2008/03/18 00:07:11 drh Exp $
  16. */
  17. #include "sqliteInt.h"
  18. /*
  19. ** This version of the memory allocator is the default.  It is
  20. ** used when no other memory allocator is specified using compile-time
  21. ** macros.
  22. */
  23. #if 1 /* szhy:081105 */
  24. #include "sqlite3_port.h"
  25. extern SQLITE3_port_s SQLITE3_port;
  26. extern int        SQLITE3_debug;
  27. static int            SQLITE3_max;
  28. #endif
  29. #ifdef SQLITE_SYSTEM_MALLOC
  30. /*
  31. ** All of the static variables used by this module are collected
  32. ** into a single structure named "mem".  This is to keep the
  33. ** static variables organized and to reduce namespace pollution
  34. ** when this module is combined with other in the amalgamation.
  35. */
  36. static struct {
  37.   /*
  38.   ** The alarm callback and its arguments.  The mem.mutex lock will
  39.   ** be held while the callback is running.  Recursive calls into
  40.   ** the memory subsystem are allowed, but no new callbacks will be
  41.   ** issued.  The alarmBusy variable is set to prevent recursive
  42.   ** callbacks.
  43.   */
  44.   sqlite3_int64 alarmThreshold;
  45.   void (*alarmCallback)(void*, sqlite3_int64,int);
  46.   void *alarmArg;
  47.   int alarmBusy;
  48.   
  49.   /*
  50.   ** Mutex to control access to the memory allocation subsystem.
  51.   */
  52.   sqlite3_mutex *mutex;
  53.   
  54.   /*
  55.   ** Current allocation and high-water mark.
  56.   */
  57.   sqlite3_int64 nowUsed;
  58.   sqlite3_int64 mxUsed;
  59.   
  60.  
  61. } mem;
  62. /*
  63. ** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
  64. */
  65. static void enterMem(void){
  66.   if( mem.mutex==0 ){
  67.     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  68.   }
  69.   sqlite3_mutex_enter(mem.mutex);
  70. }
  71. /*
  72. ** Return the amount of memory currently checked out.
  73. */
  74. sqlite3_int64 sqlite3_memory_used(void){
  75.   sqlite3_int64 n;
  76.   enterMem();
  77.   n = mem.nowUsed;
  78.   sqlite3_mutex_leave(mem.mutex);  
  79.   return n;
  80. }
  81. /*
  82. ** Return the maximum amount of memory that has ever been
  83. ** checked out since either the beginning of this process
  84. ** or since the most recent reset.
  85. */
  86. sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
  87.   sqlite3_int64 n;
  88.   enterMem();
  89.   n = mem.mxUsed;
  90.   if( resetFlag ){
  91.     mem.mxUsed = mem.nowUsed;
  92.   }
  93.   sqlite3_mutex_leave(mem.mutex);  
  94.   return n;
  95. }
  96. /*
  97. ** Change the alarm callback
  98. */
  99. int sqlite3_memory_alarm(
  100.   void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
  101.   void *pArg,
  102.   sqlite3_int64 iThreshold
  103. ){
  104.   enterMem();
  105.   mem.alarmCallback = xCallback;
  106.   mem.alarmArg = pArg;
  107.   mem.alarmThreshold = iThreshold;
  108.   sqlite3_mutex_leave(mem.mutex);
  109.   return SQLITE_OK;
  110. }
  111. /*
  112. ** Trigger the alarm 
  113. */
  114. static void sqlite3MemsysAlarm(int nByte){
  115.   void (*xCallback)(void*,sqlite3_int64,int);
  116.   sqlite3_int64 nowUsed;
  117.   void *pArg;
  118.   if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
  119.   mem.alarmBusy = 1;
  120.   xCallback = mem.alarmCallback;
  121.   nowUsed = mem.nowUsed;
  122.   pArg = mem.alarmArg;
  123.   sqlite3_mutex_leave(mem.mutex);
  124.   xCallback(pArg, nowUsed, nByte);
  125.   sqlite3_mutex_enter(mem.mutex);
  126.   mem.alarmBusy = 0;
  127. }
  128. /*
  129. ** Allocate nBytes of memory
  130. */
  131. void *sqlite3_malloc(int nBytes){
  132.   sqlite3_int64 *p = 0;
  133.   if( nBytes>0 ){
  134.     enterMem();
  135.     if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
  136.       sqlite3MemsysAlarm(nBytes);
  137.     }
  138.     if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
  139.       p = 0;
  140.     }else{
  141.     if(SQLITE3_port.SQLITE3_port_malloc)
  142.     {
  143. p = SQLITE3_port.SQLITE3_port_malloc(nBytes+8);
  144.     }
  145. else
  146. {
  147.         p = malloc(nBytes+8);
  148. }
  149.       if( p==0 ){
  150.         sqlite3MemsysAlarm(nBytes);
  151. if(SQLITE3_port.SQLITE3_port_malloc)
  152. {
  153. p = SQLITE3_port.SQLITE3_port_malloc(nBytes+8);
  154. }
  155. else
  156. {
  157.          p = malloc(nBytes+8);
  158. }
  159.       }
  160.     }
  161.     if( p ){
  162.       p[0] = nBytes;
  163.       p++;
  164.       mem.nowUsed += nBytes;
  165.       if( mem.nowUsed>mem.mxUsed ){
  166.         mem.mxUsed = mem.nowUsed;
  167.       }
  168.     }
  169.     sqlite3_mutex_leave(mem.mutex);
  170.   }
  171. #if 1
  172.  if(SQLITE3_debug)
  173.  {
  174.  if(SQLITE3_port.SQLITE3_port_printf && mem.nowUsed>SQLITE3_max)
  175.  {
  176.  char inf[50];
  177.  SQLITE3_max = mem.nowUsed; 
  178.  sprintf(inf,"SQLITE3 memory used:%d Bytes.n",mem.nowUsed);
  179.  SQLITE3_port.SQLITE3_port_printf(inf);
  180.  }
  181.  }
  182. #endif
  183.   return (void*)p; 
  184. }
  185. /*
  186. ** Free memory.
  187. */
  188. void sqlite3_free(void *pPrior){
  189.   sqlite3_int64 *p;
  190.   int nByte;
  191.   if( pPrior==0 ){
  192.     return;
  193.   }
  194.   assert( mem.mutex!=0 );
  195.   p = pPrior;
  196.   p--;
  197.   nByte = (int)*p;
  198.   sqlite3_mutex_enter(mem.mutex);
  199.   mem.nowUsed -= nByte;
  200.   if(SQLITE3_port.SQLITE3_port_free)
  201.   {
  202.    SQLITE3_port.SQLITE3_port_free(p);
  203.   }
  204.   else
  205.   {
  206.    free(p);
  207.   }
  208.   sqlite3_mutex_leave(mem.mutex);  
  209. #if 0
  210. if(SQLITE3_debug)
  211. {
  212. if(SQLITE3_port.SQLITE3_port_printf)
  213. {
  214. char inf[50];
  215. sprintf(inf,"SQLITE3 memory used:%d Bytes.n",mem.nowUsed);
  216. SQLITE3_port.SQLITE3_port_printf(inf);
  217. }
  218. }
  219. #endif
  220. }
  221. /*
  222. ** Return the number of bytes allocated at p.
  223. */
  224. int sqlite3MallocSize(void *p){
  225.   sqlite3_int64 *pInt;
  226.   if( !p ) return 0;
  227.   pInt = p;
  228.   return pInt[-1];
  229. }
  230. /*
  231. ** Change the size of an existing memory allocation
  232. */
  233. void *sqlite3_realloc(void *pPrior, int nBytes){
  234.   int nOld;
  235.   sqlite3_int64 *p;
  236.   if( pPrior==0 ){
  237.     return sqlite3_malloc(nBytes);
  238.   }
  239.   if( nBytes<=0 ){
  240.     sqlite3_free(pPrior);
  241.     return 0;
  242.   }
  243.   p = pPrior;
  244.   p--;
  245.   nOld = (int)p[0];
  246.   assert( mem.mutex!=0 );
  247.   sqlite3_mutex_enter(mem.mutex);
  248.   if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
  249.     sqlite3MemsysAlarm(nBytes-nOld);
  250.   }
  251.   if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
  252.     p = 0;
  253.   }else{
  254.   if(SQLITE3_port.SQLITE3_port_realloc)
  255.   {
  256.    p = SQLITE3_port.SQLITE3_port_realloc(p, nBytes+8);
  257.   }
  258.   else
  259.   {
  260.     p = realloc(p, nBytes+8);
  261.   }
  262.     if( p==0 ){
  263.       sqlite3MemsysAlarm(nBytes);
  264.       p = pPrior;
  265.       p--;
  266.   if(SQLITE3_port.SQLITE3_port_realloc)
  267.   {
  268.    p = SQLITE3_port.SQLITE3_port_realloc(p,nBytes+8);
  269.   }
  270.   {
  271.        p = realloc(p, nBytes+8);
  272.   }
  273.     }
  274.   }
  275.   if( p ){
  276.     p[0] = nBytes;
  277.     p++;
  278.     mem.nowUsed += nBytes-nOld;
  279.     if( mem.nowUsed>mem.mxUsed ){
  280.       mem.mxUsed = mem.nowUsed;
  281.     }
  282.   }
  283.   sqlite3_mutex_leave(mem.mutex);
  284.  #if 1
  285. if(SQLITE3_debug)
  286. {
  287. if(SQLITE3_port.SQLITE3_port_printf && mem.nowUsed>SQLITE3_max)
  288. {
  289. char inf[50];
  290. SQLITE3_max = mem.nowUsed;
  291. sprintf(inf,"SQLITE3 memory used:%d Bytes.n",mem.nowUsed);
  292. SQLITE3_port.SQLITE3_port_printf(inf);
  293. }
  294. }
  295.  #endif
  296.   return (void*)p;
  297. }
  298. #endif /* SQLITE_SYSTEM_MALLOC */