/ Check-in [80c63443]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Minor changes to unixMapfile() function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | two-mappings
Files: files | file ages | folders
SHA1: 80c63443c438ec21cc02880801d4fb4ca5f4e23f
User & Date: dan 2013-04-01 14:20:23
Context
2013-04-01
14:20
Minor changes to unixMapfile() function. Leaf check-in: 80c63443 user: dan tags: two-mappings
2013-03-29
19:38
Further fixes for test scripts. check-in: 23ffa4f9 user: dan tags: two-mappings
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  4586   4586   ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
  4587   4587   **
  4588   4588   ** SQLITE_OK is returned if no error occurs (even if the mapping is not
  4589   4589   ** recreated as a result of outstanding references) or an SQLite error
  4590   4590   ** code otherwise.
  4591   4591   */
  4592   4592   static int unixMapfile(unixFile *pFd, i64 nByte){
  4593         -  i64 nMap = nByte;
         4593  +  i64 nMap;                       /* Number of bytes of file to map */
  4594   4594     int rc;
  4595   4595   
  4596   4596     assert( nMap>=0 || pFd->nFetchOut==0 );
  4597   4597     if( pFd->nFetchOut>0 ) return SQLITE_OK;
  4598   4598   
         4599  +  /* Set variable nMap to the number of bytes of the file to map. This is
         4600  +  ** the smaller of argument nByte and the limit configured by
         4601  +  ** SQLITE_FCNTL_MMAP_LIMIT. Or, if nByte is less than zero, the smaller
         4602  +  ** of the file size or the SQLITE_FCNTL_MMAP_LIMIT value.  */
         4603  +  nMap = nByte;
  4599   4604     if( nMap<0 ){
  4600   4605       struct stat statbuf;          /* Low-level file information */
  4601   4606       rc = osFstat(pFd->h, &statbuf);
  4602   4607       if( rc!=SQLITE_OK ){
  4603   4608         return SQLITE_IOERR_FSTAT;
  4604   4609       }
  4605   4610       nMap = statbuf.st_size;
  4606   4611     }
  4607   4612     if( nMap>pFd->mmapLimit ){
  4608   4613       nMap = pFd->mmapLimit;
  4609   4614     }
  4610   4615   
  4611   4616     if( nMap!=(pFd->aMmap[0].mmapSize + pFd->aMmap[1].mmapSize) ){
  4612         -    void *pNew = 0;
  4613   4617   
  4614   4618       /* If the request is for a mapping zero bytes in size, or there are 
  4615   4619       ** currently already two mapping regions, or there is already a mapping
  4616   4620       ** region that is not a multiple of the page-size in size, unmap
  4617   4621       ** everything.  */
  4618   4622       if( nMap==0 
  4619   4623   #if !HAVE_MREMAP
  4620         -     || (pFd->aMmap[0].pMapRegion && pFd->aMmap[1].pMapRegion) 
         4624  +     || (pFd->aMmap[0].pMapRegion && pFd->aMmap[1].pMapRegion)
  4621   4625        || (pFd->aMmap[0].mmapSize % pFd->szSyspage)
  4622   4626   #endif
  4623   4627       ){
  4624   4628         unixUnmapfile(pFd);
  4625   4629       }
  4626   4630       assert( pFd->aMmap[1].pMapRegion==0 );
  4627   4631   
  4628   4632       if( nMap>0 ){
         4633  +      unixMapping *pMap = &pFd->aMmap[0];   /* First mapping object */
         4634  +      void *pNew = 0;
         4635  +      int iNew = 0;
  4629   4636         int flags = PROT_READ;
  4630   4637         if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
  4631   4638   
  4632   4639         /* If there are currently no mappings, create a new one */
  4633         -      if( pFd->aMmap[0].pMapRegion==0 ){
         4640  +      if( pMap->pMapRegion==0 ){
  4634   4641           pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);
  4635         -        if( pNew==MAP_FAILED ){
  4636         -          return SQLITE_IOERR_MMAP;
  4637         -        }
  4638         -        pFd->aMmap[0].pMapRegion = pNew;
  4639         -        pFd->aMmap[0].mmapSize = nMap;
  4640         -        pFd->aMmap[0].mmapOrigsize = nMap;
  4641   4642         }
  4642   4643   #if HAVE_MREMAP
  4643   4644         /* If we have an mremap() call, resize the existing mapping. */
  4644   4645         else{
  4645         -        unixMapping *pMap = &pFd->aMmap[0];
  4646   4646           pNew = osMremap(
  4647   4647               pMap->pMapRegion, pMap->mmapOrigsize, nMap, MREMAP_MAYMOVE
  4648   4648           );
  4649         -        if( pNew==MAP_FAILED ){
  4650         -          return SQLITE_IOERR_MMAP;
  4651         -        }
  4652         -        pFd->aMmap[0].pMapRegion = pNew;
  4653         -        pFd->aMmap[0].mmapSize = nMap;
  4654         -        pFd->aMmap[0].mmapOrigsize = nMap;
  4655   4649         }
  4656   4650   #else
  4657   4651         /* Otherwise, create a second mapping. If the existing mapping is
  4658   4652         ** a multiple of the page-size in size, then request that the new
  4659   4653         ** mapping immediately follow the old in virtual memory.  */
  4660   4654         else{
  4661         -        unixMapping *pMap = &pFd->aMmap[0];
  4662         -        void *pAddr = 0;
         4655  +        i64 nNew;                 /* Bytes to map with this call */
         4656  +        void *pAddr = 0;          /* Virtual address to request mapping at */
  4663   4657   
  4664         -        nMap -= pMap->mmapSize;
  4665         -
         4658  +        nNew = nMap - pMap->mmapSize;
  4666   4659           if( pMap->mmapSize==pMap->mmapOrigsize ){
  4667   4660             pAddr = (void *)&((u8 *)pMap->pMapRegion)[pMap->mmapSize];
  4668   4661           }
  4669   4662   
  4670         -        pNew = osMmap(pAddr, nMap, flags, MAP_SHARED, pFd->h, pMap->mmapSize);
  4671         -        if( pNew==MAP_FAILED ){
  4672         -          return SQLITE_IOERR_MMAP;
  4673         -        }
  4674         -        if( pNew==pAddr ){
  4675         -          pMap->mmapOrigsize += nMap;
  4676         -          pMap->mmapSize += nMap;
         4663  +        pNew = osMmap(pAddr, nNew, flags, MAP_SHARED, pFd->h, pMap->mmapSize);
         4664  +
         4665  +        if( pAddr && pNew==pAddr ){
         4666  +          pNew = pMap->pMapRegion;
  4677   4667           }else{
  4678         -          pFd->aMmap[1].pMapRegion = pNew;
  4679         -          pFd->aMmap[1].mmapSize = nMap;
  4680         -          pFd->aMmap[1].mmapOrigsize = nMap;
         4668  +          iNew = 1;
         4669  +          nMap = nNew;
  4681   4670           }
  4682   4671         }
  4683   4672   #endif
         4673  +
         4674  +      if( pNew==MAP_FAILED ){
         4675  +        return SQLITE_IOERR_MMAP;
         4676  +      }
         4677  +      pFd->aMmap[iNew].pMapRegion = pNew;
         4678  +      pFd->aMmap[iNew].mmapSize = nMap;
         4679  +      pFd->aMmap[iNew].mmapOrigsize = nMap;
  4684   4680       }
  4685   4681     }
  4686   4682   
  4687   4683     return SQLITE_OK;
  4688   4684   }
  4689   4685   
  4690   4686   /*