SQLite

Check-in [80c63443c4]
Login

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

Overview
Comment:Minor changes to unixMapfile() function.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | two-mappings
Files: files | file ages | folders
SHA1: 80c63443c438ec21cc02880801d4fb4ca5f4e23f
User & Date: dan 2013-04-01 14:20:23.253
Context
2013-04-01
14:20
Minor changes to unixMapfile() function. (Leaf check-in: 80c63443c4 user: dan tags: two-mappings)
2013-03-29
19:38
Further fixes for test scripts. (check-in: 23ffa4f9fb user: dan tags: two-mappings)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598





4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628



4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683







4684
4685
4686
4687
4688
4689
4690
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
  i64 nMap = nByte;
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;






  if( nMap<0 ){
    struct stat statbuf;          /* Low-level file information */
    rc = osFstat(pFd->h, &statbuf);
    if( rc!=SQLITE_OK ){
      return SQLITE_IOERR_FSTAT;
    }
    nMap = statbuf.st_size;
  }
  if( nMap>pFd->mmapLimit ){
    nMap = pFd->mmapLimit;
  }

  if( nMap!=(pFd->aMmap[0].mmapSize + pFd->aMmap[1].mmapSize) ){
    void *pNew = 0;

    /* If the request is for a mapping zero bytes in size, or there are 
    ** currently already two mapping regions, or there is already a mapping
    ** region that is not a multiple of the page-size in size, unmap
    ** everything.  */
    if( nMap==0 
#if !HAVE_MREMAP
     || (pFd->aMmap[0].pMapRegion && pFd->aMmap[1].pMapRegion) 
     || (pFd->aMmap[0].mmapSize % pFd->szSyspage)
#endif
    ){
      unixUnmapfile(pFd);
    }
    assert( pFd->aMmap[1].pMapRegion==0 );

    if( nMap>0 ){



      int flags = PROT_READ;
      if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;

      /* If there are currently no mappings, create a new one */
      if( pFd->aMmap[0].pMapRegion==0 ){
        pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);
        if( pNew==MAP_FAILED ){
          return SQLITE_IOERR_MMAP;
        }
        pFd->aMmap[0].pMapRegion = pNew;
        pFd->aMmap[0].mmapSize = nMap;
        pFd->aMmap[0].mmapOrigsize = nMap;
      }
#if HAVE_MREMAP
      /* If we have an mremap() call, resize the existing mapping. */
      else{
        unixMapping *pMap = &pFd->aMmap[0];
        pNew = osMremap(
            pMap->pMapRegion, pMap->mmapOrigsize, nMap, MREMAP_MAYMOVE
        );
        if( pNew==MAP_FAILED ){
          return SQLITE_IOERR_MMAP;
        }
        pFd->aMmap[0].pMapRegion = pNew;
        pFd->aMmap[0].mmapSize = nMap;
        pFd->aMmap[0].mmapOrigsize = nMap;
      }
#else
      /* Otherwise, create a second mapping. If the existing mapping is
      ** a multiple of the page-size in size, then request that the new
      ** mapping immediately follow the old in virtual memory.  */
      else{
        unixMapping *pMap = &pFd->aMmap[0];
        void *pAddr = 0;

        nMap -= pMap->mmapSize;

        if( pMap->mmapSize==pMap->mmapOrigsize ){
          pAddr = (void *)&((u8 *)pMap->pMapRegion)[pMap->mmapSize];
        }

        pNew = osMmap(pAddr, nMap, flags, MAP_SHARED, pFd->h, pMap->mmapSize);
        if( pNew==MAP_FAILED ){
          return SQLITE_IOERR_MMAP;
        }
        if( pNew==pAddr ){
          pMap->mmapOrigsize += nMap;
          pMap->mmapSize += nMap;
        }else{
          pFd->aMmap[1].pMapRegion = pNew;
          pFd->aMmap[1].mmapSize = nMap;
          pFd->aMmap[1].mmapOrigsize = nMap;
        }
      }
#endif







    }
  }

  return SQLITE_OK;
}

/*







|





>
>
>
>
>













<







|








>
>
>




|

<
<
<
<
<
<




<



<
<
<
<
<
<






|
|

|
<




|
<
<
|
|
<
|

|
|
<



>
>
>
>
>
>
>







4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616

4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641






4642
4643
4644
4645

4646
4647
4648






4649
4650
4651
4652
4653
4654
4655
4656
4657
4658

4659
4660
4661
4662
4663


4664
4665

4666
4667
4668
4669

4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller.
**
** SQLITE_OK is returned if no error occurs (even if the mapping is not
** recreated as a result of outstanding references) or an SQLite error
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
  i64 nMap;                       /* Number of bytes of file to map */
  int rc;

  assert( nMap>=0 || pFd->nFetchOut==0 );
  if( pFd->nFetchOut>0 ) return SQLITE_OK;

  /* Set variable nMap to the number of bytes of the file to map. This is
  ** the smaller of argument nByte and the limit configured by
  ** SQLITE_FCNTL_MMAP_LIMIT. Or, if nByte is less than zero, the smaller
  ** of the file size or the SQLITE_FCNTL_MMAP_LIMIT value.  */
  nMap = nByte;
  if( nMap<0 ){
    struct stat statbuf;          /* Low-level file information */
    rc = osFstat(pFd->h, &statbuf);
    if( rc!=SQLITE_OK ){
      return SQLITE_IOERR_FSTAT;
    }
    nMap = statbuf.st_size;
  }
  if( nMap>pFd->mmapLimit ){
    nMap = pFd->mmapLimit;
  }

  if( nMap!=(pFd->aMmap[0].mmapSize + pFd->aMmap[1].mmapSize) ){


    /* If the request is for a mapping zero bytes in size, or there are 
    ** currently already two mapping regions, or there is already a mapping
    ** region that is not a multiple of the page-size in size, unmap
    ** everything.  */
    if( nMap==0 
#if !HAVE_MREMAP
     || (pFd->aMmap[0].pMapRegion && pFd->aMmap[1].pMapRegion)
     || (pFd->aMmap[0].mmapSize % pFd->szSyspage)
#endif
    ){
      unixUnmapfile(pFd);
    }
    assert( pFd->aMmap[1].pMapRegion==0 );

    if( nMap>0 ){
      unixMapping *pMap = &pFd->aMmap[0];   /* First mapping object */
      void *pNew = 0;
      int iNew = 0;
      int flags = PROT_READ;
      if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;

      /* If there are currently no mappings, create a new one */
      if( pMap->pMapRegion==0 ){
        pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);






      }
#if HAVE_MREMAP
      /* If we have an mremap() call, resize the existing mapping. */
      else{

        pNew = osMremap(
            pMap->pMapRegion, pMap->mmapOrigsize, nMap, MREMAP_MAYMOVE
        );






      }
#else
      /* Otherwise, create a second mapping. If the existing mapping is
      ** a multiple of the page-size in size, then request that the new
      ** mapping immediately follow the old in virtual memory.  */
      else{
        i64 nNew;                 /* Bytes to map with this call */
        void *pAddr = 0;          /* Virtual address to request mapping at */

        nNew = nMap - pMap->mmapSize;

        if( pMap->mmapSize==pMap->mmapOrigsize ){
          pAddr = (void *)&((u8 *)pMap->pMapRegion)[pMap->mmapSize];
        }

        pNew = osMmap(pAddr, nNew, flags, MAP_SHARED, pFd->h, pMap->mmapSize);



        if( pAddr && pNew==pAddr ){

          pNew = pMap->pMapRegion;
        }else{
          iNew = 1;
          nMap = nNew;

        }
      }
#endif

      if( pNew==MAP_FAILED ){
        return SQLITE_IOERR_MMAP;
      }
      pFd->aMmap[iNew].pMapRegion = pNew;
      pFd->aMmap[iNew].mmapSize = nMap;
      pFd->aMmap[iNew].mmapOrigsize = nMap;
    }
  }

  return SQLITE_OK;
}

/*