⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem2.c

📁 嵌入式数据系统软件!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2007 August 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** This file contains the C functions that implement a memory** allocation subsystem for use by SQLite.  **** $Id: mem2.c,v 1.18 2007/11/29 18:36:49 drh Exp $*//*** This version of the memory allocator is used only if the** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION** is not defined.*/#if defined(SQLITE_MEMDEBUG)/*** We will eventually construct multiple memory allocation subsystems** suitable for use in various contexts:****    *  Normal multi-threaded builds**    *  Normal single-threaded builds**    *  Debugging builds**** This version is suitable for use in debugging builds.**** Features:****    * Every allocate has guards at both ends.**    * New allocations are initialized with randomness**    * Allocations are overwritten with randomness when freed**    * Optional logs of malloc activity generated**    * Summary of outstanding allocations with backtraces to the**      point of allocation.**    * The ability to simulate memory allocation failure*/#include "sqliteInt.h"#include <stdio.h>/*** The backtrace functionality is only available with GLIBC*/#ifdef __GLIBC__  extern int backtrace(void**,int);  extern void backtrace_symbols_fd(void*const*,int,int);#else# define backtrace(A,B) 0# define backtrace_symbols_fd(A,B,C)#endif/*** Each memory allocation looks like this:****  ------------------------------------------------------------------------**  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |**  ------------------------------------------------------------------------**** The application code sees only a pointer to the allocation.  We have** to back up from the allocation pointer to find the MemBlockHdr.  The** MemBlockHdr tells us the size of the allocation and the number of** backtrace pointers.  There is also a guard word at the end of the** MemBlockHdr.*/struct MemBlockHdr {  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */  int iSize;                          /* Size of this allocation */  char nBacktrace;                    /* Number of backtraces on this alloc */  char nBacktraceSlots;               /* Available backtrace slots */  short nTitle;                       /* Bytes of title; includes '\0' */  int iForeGuard;                     /* Guard word for sanity */};/*** Guard words*/#define FOREGUARD 0x80F5E153#define REARGUARD 0xE4676B53/*** Number of malloc size increments to track.*/#define NCSIZE  1000/*** All of the static variables used by this module are collected** into a single structure named "mem".  This is to keep the** static variables organized and to reduce namespace pollution** when this module is combined with other in the amalgamation.*/static struct {  /*  ** The alarm callback and its arguments.  The mem.mutex lock will  ** be held while the callback is running.  Recursive calls into  ** the memory subsystem are allowed, but no new callbacks will be  ** issued.  The alarmBusy variable is set to prevent recursive  ** callbacks.  */  sqlite3_int64 alarmThreshold;  void (*alarmCallback)(void*, sqlite3_int64, int);  void *alarmArg;  int alarmBusy;    /*  ** Mutex to control access to the memory allocation subsystem.  */  sqlite3_mutex *mutex;    /*  ** Current allocation and high-water mark.  */  sqlite3_int64 nowUsed;  sqlite3_int64 mxUsed;    /*  ** Head and tail of a linked list of all outstanding allocations  */  struct MemBlockHdr *pFirst;  struct MemBlockHdr *pLast;    /*  ** The number of levels of backtrace to save in new allocations.  */  int nBacktrace;  /*  ** Title text to insert in front of each block  */  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */  char zTitle[100];  /* The title text */  /*  ** These values are used to simulate malloc failures.  When  ** iFail is 1, simulate a malloc failures and reset the value  ** to iReset.  */  int iFail;    /* Decrement and fail malloc when this is 1 */  int iReset;   /* When malloc fails set iiFail to this value */  int iFailCnt;         /* Number of failures */  int iBenignFailCnt;   /* Number of benign failures */  int iNextIsBenign;    /* True if the next call to malloc may fail benignly */  int iIsBenign;        /* All malloc calls may fail benignly */  /*   ** sqlite3MallocDisallow() increments the following counter.  ** sqlite3MallocAllow() decrements it.  */  int disallow; /* Do not allow memory allocation */  /*  ** Gather statistics on the sizes of memory allocations.  ** sizeCnt[i] is the number of allocation attempts of i*8  ** bytes.  i==NCSIZE is the number of allocation attempts for  ** sizes more than NCSIZE*8 bytes.  */  int sizeCnt[NCSIZE];} mem;/*** Enter the mutex mem.mutex. Allocate it if it is not already allocated.*/static void enterMem(void){  if( mem.mutex==0 ){    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);  }  sqlite3_mutex_enter(mem.mutex);}/*** Return the amount of memory currently checked out.*/sqlite3_int64 sqlite3_memory_used(void){  sqlite3_int64 n;  enterMem();  n = mem.nowUsed;  sqlite3_mutex_leave(mem.mutex);    return n;}/*** Return the maximum amount of memory that has ever been** checked out since either the beginning of this process** or since the most recent reset.*/sqlite3_int64 sqlite3_memory_highwater(int resetFlag){  sqlite3_int64 n;  enterMem();  n = mem.mxUsed;  if( resetFlag ){    mem.mxUsed = mem.nowUsed;  }  sqlite3_mutex_leave(mem.mutex);    return n;}/*** Change the alarm callback*/int sqlite3_memory_alarm(  void(*xCallback)(void *pArg, sqlite3_int64 used, int N),  void *pArg,  sqlite3_int64 iThreshold){  enterMem();  mem.alarmCallback = xCallback;  mem.alarmArg = pArg;  mem.alarmThreshold = iThreshold;  sqlite3_mutex_leave(mem.mutex);  return SQLITE_OK;}/*** Trigger the alarm */static void sqlite3MemsysAlarm(int nByte){  void (*xCallback)(void*,sqlite3_int64,int);  sqlite3_int64 nowUsed;  void *pArg;  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;  mem.alarmBusy = 1;  xCallback = mem.alarmCallback;  nowUsed = mem.nowUsed;  pArg = mem.alarmArg;  sqlite3_mutex_leave(mem.mutex);  xCallback(pArg, nowUsed, nByte);  sqlite3_mutex_enter(mem.mutex);  mem.alarmBusy = 0;}/*** Given an allocation, find the MemBlockHdr for that allocation.**** This routine checks the guards at either end of the allocation and** if they are incorrect it asserts.*/static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){  struct MemBlockHdr *p;  int *pInt;  p = (struct MemBlockHdr*)pAllocation;  p--;  assert( p->iForeGuard==FOREGUARD );  assert( (p->iSize & 3)==0 );  pInt = (int*)pAllocation;  assert( pInt[p->iSize/sizeof(int)]==REARGUARD );  return p;}/*** This routine is called once the first time a simulated memory** failure occurs.  The sole purpose of this routine is to provide** a convenient place to set a debugger breakpoint when debugging** errors related to malloc() failures.*/static void sqlite3MemsysFailed(void){  mem.iFailCnt = 0;  mem.iBenignFailCnt = 0;}/*** Allocate nByte bytes of memory.*/void *sqlite3_malloc(int nByte){  struct MemBlockHdr *pHdr;  void **pBt;  char *z;  int *pInt;  void *p = 0;  int totalSize;  if( nByte>0 ){    enterMem();    assert( mem.disallow==0 );    if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){      sqlite3MemsysAlarm(nByte);    }    nByte = (nByte+3)&~3;    if( nByte/8>NCSIZE-1 ){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -