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

📄 mem3.c

📁 嵌入式数据系统软件!
💻 C
📖 第 1 页 / 共 2 页
字号:
    void *p = memsys3Checkout(mem.iMaster, mem.szMaster);    mem.iMaster = 0;    mem.szMaster = 0;    mem.mnMaster = 0;    return p;  }else{    /* Split the master block.  Return the tail. */    int newi;    newi = mem.iMaster + mem.szMaster - nBlock;    assert( newi > mem.iMaster+1 );    mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = -nBlock;    mem.aPool[newi-1].u.hdr.size = -nBlock;    mem.szMaster -= nBlock;    mem.aPool[newi-1].u.hdr.prevSize = mem.szMaster;    mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;    if( mem.szMaster < mem.mnMaster ){      mem.mnMaster = mem.szMaster;    }    return (void*)&mem.aPool[newi];  }}/*** *pRoot is the head of a list of free chunks of the same size** or same size hash.  In other words, *pRoot is an entry in either** mem.aiSmall[] or mem.aiHash[].  **** This routine examines all entries on the given list and tries** to coalesce each entries with adjacent free chunks.  **** If it sees a chunk that is larger than mem.iMaster, it replaces ** the current mem.iMaster with the new larger chunk.  In order for** this mem.iMaster replacement to work, the master chunk must be** linked into the hash tables.  That is not the normal state of** affairs, of course.  The calling routine must link the master** chunk before invoking this routine, then must unlink the (possibly** changed) master chunk once this routine has finished.*/static void memsys3Merge(int *pRoot){  int iNext, prev, size, i;  assert( sqlite3_mutex_held(mem.mutex) );  for(i=*pRoot; i>0; i=iNext){    iNext = mem.aPool[i].u.list.next;    size = mem.aPool[i-1].u.hdr.size;    assert( size>0 );    if( mem.aPool[i-1].u.hdr.prevSize>0 ){      memsys3UnlinkFromList(i, pRoot);      prev = i - mem.aPool[i-1].u.hdr.prevSize;      assert( prev>=0 );      if( prev==iNext ){        iNext = mem.aPool[prev].u.list.next;      }      memsys3Unlink(prev);      size = i + size - prev;      mem.aPool[prev-1].u.hdr.size = size;      mem.aPool[prev+size-1].u.hdr.prevSize = size;      memsys3Link(prev);      i = prev;    }    if( size>mem.szMaster ){      mem.iMaster = i;      mem.szMaster = size;    }  }}/*** Return a block of memory of at least nBytes in size.** Return NULL if unable.*/static void *memsys3Malloc(int nByte){  int i;  int nBlock;  int toFree;  assert( sqlite3_mutex_held(mem.mutex) );  assert( sizeof(Mem3Block)==8 );  if( nByte<=0 ){    nBlock = 2;  }else{    nBlock = (nByte + 15)/8;  }  assert( nBlock >= 2 );  /* STEP 1:  ** Look for an entry of the correct size in either the small  ** chunk table or in the large chunk hash table.  This is  ** successful most of the time (about 9 times out of 10).  */  if( nBlock <= MX_SMALL ){    i = mem.aiSmall[nBlock-2];    if( i>0 ){      memsys3UnlinkFromList(i, &mem.aiSmall[nBlock-2]);      return memsys3Checkout(i, nBlock);    }  }else{    int hash = nBlock % N_HASH;    for(i=mem.aiHash[hash]; i>0; i=mem.aPool[i].u.list.next){      if( mem.aPool[i-1].u.hdr.size==nBlock ){        memsys3UnlinkFromList(i, &mem.aiHash[hash]);        return memsys3Checkout(i, nBlock);      }    }  }  /* STEP 2:  ** Try to satisfy the allocation by carving a piece off of the end  ** of the master chunk.  This step usually works if step 1 fails.  */  if( mem.szMaster>=nBlock ){    return memsys3FromMaster(nBlock);  }  /* STEP 3:    ** Loop through the entire memory pool.  Coalesce adjacent free  ** chunks.  Recompute the master chunk as the largest free chunk.  ** Then try again to satisfy the allocation by carving a piece off  ** of the end of the master chunk.  This step happens very  ** rarely (we hope!)  */  for(toFree=nBlock*16; toFree<SQLITE_MEMORY_SIZE*2; toFree *= 2){    memsys3OutOfMemory(toFree);    if( mem.iMaster ){      memsys3Link(mem.iMaster);      mem.iMaster = 0;      mem.szMaster = 0;    }    for(i=0; i<N_HASH; i++){      memsys3Merge(&mem.aiHash[i]);    }    for(i=0; i<MX_SMALL-1; i++){      memsys3Merge(&mem.aiSmall[i]);    }    if( mem.szMaster ){      memsys3Unlink(mem.iMaster);      if( mem.szMaster>=nBlock ){        return memsys3FromMaster(nBlock);      }    }  }  /* If none of the above worked, then we fail. */  return 0;}/*** Free an outstanding memory allocation.*/void memsys3Free(void *pOld){  Mem3Block *p = (Mem3Block*)pOld;  int i;  int size;  assert( sqlite3_mutex_held(mem.mutex) );  assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] );  i = p - mem.aPool;  size = -mem.aPool[i-1].u.hdr.size;  assert( size>=2 );  assert( mem.aPool[i+size-1].u.hdr.prevSize==-size );  mem.aPool[i-1].u.hdr.size = size;  mem.aPool[i+size-1].u.hdr.prevSize = size;  memsys3Link(i);  /* Try to expand the master using the newly freed chunk */  if( mem.iMaster ){    while( mem.aPool[mem.iMaster-1].u.hdr.prevSize>0 ){      size = mem.aPool[mem.iMaster-1].u.hdr.prevSize;      mem.iMaster -= size;      mem.szMaster += size;      memsys3Unlink(mem.iMaster);      mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;    }    while( mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size>0 ){      memsys3Unlink(mem.iMaster+mem.szMaster);      mem.szMaster += mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size;      mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;    }  }}/*** 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; }/*** Free memory.*/void sqlite3_free(void *pPrior){  if( pPrior==0 ){    return;  }  assert( mem.mutex!=0 );  sqlite3_mutex_enter(mem.mutex);  memsys3Free(pPrior);  sqlite3_mutex_leave(mem.mutex);  }/*** Change the size of an existing memory allocation*/void *sqlite3_realloc(void *pPrior, int nBytes){  int nOld;  void *p;  if( pPrior==0 ){    return sqlite3_malloc(nBytes);  }  if( nBytes<=0 ){    sqlite3_free(pPrior);    return 0;  }  assert( mem.mutex!=0 );  nOld = memsys3Size(pPrior);  if( nBytes<=nOld && nBytes>=nOld-128 ){    return pPrior;  }  sqlite3_mutex_enter(mem.mutex);  p = memsys3Malloc(nBytes);  if( p ){    if( nOld<nBytes ){      memcpy(p, pPrior, nOld);    }else{      memcpy(p, pPrior, nBytes);    }    memsys3Free(pPrior);  }  sqlite3_mutex_leave(mem.mutex);  return p;}/*** 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}#endif /* !SQLITE_MEMORY_SIZE */

⌨️ 快捷键说明

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