//重新分配*pPrior指向的内存空间大小为n字节。 static void *memsys3Realloc(void *pPrior, int nBytes) { int nOld; void *p; if( pPrior==0 ) { //原来的内存为0,则直接分配n字节 return sqlite3_malloc(nBytes); } if( nBytes<=0 ) { sqlite3_free(pPrior); //释放从由sqlite3Malloc获得的内存空间 return 0; } nOld = memsys3Size(pPrior); //获取未完成分配的内存空间 if( nBytes<=nOld && nBytes>=nOld-128 ) { return pPrior; } memsys3Enter(); p = memsys3MallocUnsafe(nBytes); //申请n字节的内存空间 if( p ) { if( nOld<nBytes ) { memcpy(p, pPrior, nOld); } else { memcpy(p, pPrior, nBytes); } memsys3FreeUnsafe(pPrior); } memsys3Leave(); return p; }
/* ** Change the size of an existing memory allocation */ static void *memsys3Realloc(sqlite4_env*pEnv, void *pPrior, int nBytes){ int nOld; void *p; if( pPrior==0 ){ return sqlite4_malloc(pEnv, nBytes); } if( nBytes<=0 ){ sqlite4_free(pEnv, pPrior); return 0; } nOld = memsys3Size(pPrior); if( nBytes<=nOld && nBytes>=nOld-128 ){ return pPrior; } memsys3Enter(); p = memsys3MallocUnsafe(nBytes); if( p ){ if( nOld<nBytes ){ memcpy(p, pPrior, nOld); }else{ memcpy(p, pPrior, nBytes); } memsys3FreeUnsafe(pPrior); } memsys3Leave(); return p; }
/* ** Return the amount of memory currently checked out. */ sqlite3_int64 sqlite3_memory_used(void){ sqlite3_int64 n; memsys3Enter(); n = SQLITE_MEMORY_SIZE - mem.szMaster*8; sqlite3_mutex_leave(mem.mutex); return n; }
/* ** Allocate nBytes of memory. */ static void *memsys3Malloc(int nBytes){ sqlite4_int64 *p; assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ memsys3Enter(); p = memsys3MallocUnsafe(nBytes); memsys3Leave(); return (void*)p; }
//申请分配n字节的内存空间。 static void *memsys3Malloc(int nBytes) { //分配n字节的内存 sqlite3_int64 *p; assert( nBytes>0 ); /* malloc.c filters out 0 byte requests *///请求字节为0则终止程序 memsys3Enter(); //获取共享锁 p = memsys3MallocUnsafe(nBytes); //分配内存 memsys3Leave(); //释放锁 return (void*)p; //返回空指针 }
/* ** Allocate nBytes of memory */ void *sqlite3_malloc(int nBytes){ sqlite3_int64 *p = 0; if( nBytes>0 ){ memsys3Enter(); p = memsys3Malloc(nBytes); sqlite3_mutex_leave(mem.mutex); } return (void*)p; }
/* ** 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; memsys3Enter(); n = SQLITE_MEMORY_SIZE - mem.mnMaster*8; if( resetFlag ){ mem.mnMaster = mem.szMaster; } sqlite3_mutex_leave(mem.mutex); return n; }
/* ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ void sqlite4Memsys3Dump(const char *zFilename){ #ifdef SQLITE4_DEBUG FILE *out; u32 i, j; u32 size; if( zFilename==0 || zFilename[0]==0 ){ out = stdout; }else{ out = fopen(zFilename, "w"); if( out==0 ){ fprintf(stderr, "** Unable to output memory debug output log: %s **\n", zFilename); return; } } memsys3Enter(); fprintf(out, "CHUNKS:\n"); for(i=1; i<=mem3.nPool; i+=size/4){ size = mem3.aPool[i-1].u.hdr.size4x; if( size/4<=1 ){ fprintf(out, "%p size error\n", &mem3.aPool[i]); assert( 0 ); break; } if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){ fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]); assert( 0 ); break; } if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){ fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]); assert( 0 ); break; } if( size&1 ){ fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8); }else{ fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8, i==mem3.iMaster ? " **master**" : ""); } } for(i=0; i<MX_SMALL-1; i++){ if( mem3.aiSmall[i]==0 ) continue; fprintf(out, "small(%2d):", i); for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){ fprintf(out, " %p(%d)", &mem3.aPool[j], (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); } fprintf(out, "\n"); } for(i=0; i<N_HASH; i++){ if( mem3.aiHash[i]==0 ) continue; fprintf(out, "hash(%2d):", i); for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){ fprintf(out, " %p(%d)", &mem3.aPool[j], (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); } fprintf(out, "\n"); } fprintf(out, "master=%d\n", mem3.iMaster); fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); sqlite4_mutex_leave(mem3.mutex); if( out==stdout ){ fflush(stdout); }else{ fclose(out); } #else UNUSED_PARAMETER(zFilename); #endif }
/* ** Free memory. */ static void memsys3Free(void *pPrior){ assert( pPrior ); memsys3Enter(); memsys3FreeUnsafe(pPrior); memsys3Leave(); }
/* ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ void sqlite3_memdebug_dump(const char *zFilename){ #ifdef SQLITE_DEBUG FILE *out; int i, j, size; if( zFilename==0 || zFilename[0]==0 ){ out = stdout; }else{ out = fopen(zFilename, "w"); if( out==0 ){ fprintf(stderr, "** Unable to output memory debug output log: %s **\n", zFilename); return; } } memsys3Enter(); fprintf(out, "CHUNKS:\n"); for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size){ size = mem.aPool[i-1].u.hdr.size; if( size>=-1 && size<=1 ){ fprintf(out, "%p size error\n", &mem.aPool[i]); assert( 0 ); break; } if( mem.aPool[i+(size<0?-size:size)-1].u.hdr.prevSize!=size ){ fprintf(out, "%p tail size does not match\n", &mem.aPool[i]); assert( 0 ); break; } if( size<0 ){ size = -size; fprintf(out, "%p %6d bytes checked out\n", &mem.aPool[i], size*8-8); }else{ fprintf(out, "%p %6d bytes free%s\n", &mem.aPool[i], size*8-8, i==mem.iMaster ? " **master**" : ""); } } for(i=0; i<MX_SMALL-1; i++){ if( mem.aiSmall[i]==0 ) continue; fprintf(out, "small(%2d):", i); for(j = mem.aiSmall[i]; j>0; j=mem.aPool[j].u.list.next){ fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8); } fprintf(out, "\n"); } for(i=0; i<N_HASH; i++){ if( mem.aiHash[i]==0 ) continue; fprintf(out, "hash(%2d):", i); for(j = mem.aiHash[i]; j>0; j=mem.aPool[j].u.list.next){ fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8); } fprintf(out, "\n"); } fprintf(out, "master=%d\n", mem.iMaster); fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem.szMaster*8); fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem.mnMaster*8); sqlite3_mutex_leave(mem.mutex); if( out==stdout ){ fflush(stdout); }else{ fclose(out); } #endif }