/* ** 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; }
/* ** Set the title string for subsequent allocations. */ void sqlite3_memdebug_settitle(const char *zTitle) { int n = strlen(zTitle) + 1; enterMem(); if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; memcpy(mem.zTitle, zTitle, n); mem.zTitle[n] = 0; mem.nTitle = (n+3)&~3; sqlite3_mutex_leave(mem.mutex); }
/* ** 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; }
/* ** Allocate nBytes of memory */ EXPORT_C void *sqlite3_malloc(int nBytes){ sqlite3_int64 *p = 0; if( nBytes>0 ){ enterMem(); if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nBytes); } p = (sqlite3_int64*)malloc(nBytes+8); if( p==0 ){ sqlite3MemsysAlarm(nBytes); p = (sqlite3_int64*)malloc(nBytes+8); } if( p ){ p[0] = nBytes; p++; mem.nowUsed += nBytes; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; } } sqlite3_mutex_leave(mem.mutex); } return (void*)p; }
/* ** 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; totalSize = nByte + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( mem.iFail>0 ) { if( mem.iFail==1 ) { p = 0; mem.iFail = mem.iReset; if( mem.iFailCnt==0 ) { sqlite3MemsysFailed(); /* A place to set a breakpoint */ } mem.iFailCnt++; if( mem.iNextIsBenign || mem.iIsBenign ) { mem.iBenignFailCnt++; } } else { p = malloc(totalSize); mem.iFail--; } } else { p = malloc(totalSize); if( p==0 ) { sqlite3MemsysAlarm(nByte); p = malloc(totalSize); } } if( p ) { z = p; pBt = (void**)&z[mem.nTitle]; pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; pHdr->pNext = 0; pHdr->pPrev = mem.pLast; if( mem.pLast ) { mem.pLast->pNext = pHdr; } else { mem.pFirst = pHdr; } mem.pLast = pHdr; pHdr->iForeGuard = FOREGUARD; pHdr->nBacktraceSlots = mem.nBacktrace; pHdr->nTitle = mem.nTitle; if( mem.nBacktrace ) { void *aAddr[40]; pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); } else { pHdr->nBacktrace = 0; } if( mem.nTitle ) { memcpy(z, mem.zTitle, mem.nTitle); } pHdr->iSize = nByte; pInt = (int*)&pHdr[1]; pInt[nByte/sizeof(int)] = REARGUARD; memset(pInt, 0x65, nByte); mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ) { mem.mxUsed = mem.nowUsed; } p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); } mem.iNextIsBenign = 0; return p; }
/* ** 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 ){ mem.sizeCnt[NCSIZE-1]++; }else{ mem.sizeCnt[nByte/8]++; } totalSize = nByte + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ p = 0; }else{ p = malloc(totalSize); if( p==0 ){ sqlite3MemsysAlarm(nByte); p = malloc(totalSize); } } if( p ){ z = p; pBt = (void**)&z[mem.nTitle]; pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; pHdr->pNext = 0; pHdr->pPrev = mem.pLast; if( mem.pLast ){ mem.pLast->pNext = pHdr; }else{ mem.pFirst = pHdr; } mem.pLast = pHdr; pHdr->iForeGuard = FOREGUARD; pHdr->nBacktraceSlots = mem.nBacktrace; pHdr->nTitle = mem.nTitle; if( mem.nBacktrace ){ void *aAddr[40]; pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); }else{ pHdr->nBacktrace = 0; } if( mem.nTitle ){ memcpy(z, mem.zTitle, mem.nTitle); } pHdr->iSize = nByte; pInt = (int*)&pHdr[1]; pInt[nByte/sizeof(int)] = REARGUARD; memset(pInt, 0x65, nByte); mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; } p = (void*)pInt; } sqlite3_mutex_leave(mem.mutex); } return p; }