/ Check-in [c7a5880d]
Login

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

Overview
Comment:Cherrypick [ec37ad6d08] into this branch. With this patch, if SQLITE_SHARED_MAPPING is defined at build-time SQLite will use a single memory mapping for multiple connections to the same database file within a single process.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: c7a5880d6d898299b4c9414b7702cfa450aa5f7bf4ec8f417b94d2a7b6558264
User & Date: dan 2017-09-22 11:09:09
Wiki:begin-concurrent
Context
2017-11-06
10:04
Allow "BEGIN CONCURRENT" transactions to modify the temp schema. check-in: 0fb6d91c user: dan tags: begin-concurrent
2017-09-22
11:09
Cherrypick [ec37ad6d08] into this branch. With this patch, if SQLITE_SHARED_MAPPING is defined at build-time SQLite will use a single memory mapping for multiple connections to the same database file within a single process. check-in: c7a5880d user: dan tags: begin-concurrent
10:49
Merge latest trunk changes into this branch. check-in: 307b802e user: dan tags: begin-concurrent
2017-09-12
18:03
Hack to have multiple connections to a single file share a single memory mapping of the databse file. check-in: ec37ad6d user: dan tags: shared-mapping-hack
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/os_unix.c.

1111
1112
1113
1114
1115
1116
1117




1118
1119
1120
1121
1122
1123
1124
....
1245
1246
1247
1248
1249
1250
1251







1252
1253
1254
1255
1256
1257
1258
....
2051
2052
2053
2054
2055
2056
2057








2058
2059
2060
2061
2062
2063
2064
....
3870
3871
3872
3873
3874
3875
3876



3877
3878
3879
3880
3881
3882
3883
....
4770
4771
4772
4773
4774
4775
4776



4777
4778
4779
4780
4781
4782
4783
....
4900
4901
4902
4903
4904
4905
4906






















4907
4908
4909
4910
4911
4912
4913
....
5339
5340
5341
5342
5343
5344
5345



5346
5347
5348
5349
5350
5351
5352
#if SQLITE_ENABLE_LOCKING_STYLE
  unsigned long long sharedByte;  /* for AFP simulated shared lock */
#endif
#if OS_VXWORKS
  sem_t *pSem;                    /* Named POSIX semaphore */
  char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
#endif




};

/*
** A lists of all unixInodeInfo objects.
*/
static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
static unsigned int nUnusedFd = 0;    /* Total unused file descriptors */
................................................................................
static void releaseInodeInfo(unixFile *pFile){
  unixInodeInfo *pInode = pFile->pInode;
  assert( unixMutexHeld() );
  if( ALWAYS(pInode) ){
    pInode->nRef--;
    if( pInode->nRef==0 ){
      assert( pInode->pShmNode==0 );







      closePendingFds(pFile);
      if( pInode->pPrev ){
        assert( pInode->pPrev->pNext==pInode );
        pInode->pPrev->pNext = pInode->pNext;
      }else{
        assert( inodeList==pInode );
        inodeList = pInode->pNext;
................................................................................
  return SQLITE_OK;
}

/*
** Close the file.
*/
static int nolockClose(sqlite3_file *id) {








  return closeUnixFile(id);
}

/******************* End of the no-op lock implementation *********************
******************************************************************************/

/******************************************************************************
................................................................................
      if( newLimit>0 && sizeof(size_t)<8 ){
        newLimit = (newLimit & 0x7FFFFFFF);
      }

      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;



        if( pFile->mmapSize>0 ){
          unixUnmapfile(pFile);
          rc = unixMapfile(pFile, -1);
        }
      }
      return rc;
    }
................................................................................

#if SQLITE_MAX_MMAP_SIZE>0
/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );



  if( pFd->pMapRegion ){
    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapSizeActual = 0;
  }
}
................................................................................
      return SQLITE_IOERR_FSTAT;
    }
    nMap = statbuf.st_size;
  }
  if( nMap>pFd->mmapSizeMax ){
    nMap = pFd->mmapSizeMax;
  }























  assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
  if( nMap!=pFd->mmapSize ){
    unixRemapfile(pFd, nMap);
  }

  return SQLITE_OK;
................................................................................
#endif
  }

  if( pLockingStyle == &posixIoMethods
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
    || pLockingStyle == &nfsIoMethods
#endif



  ){
    unixEnterMutex();
    rc = findInodeInfo(pNew, &pNew->pInode);
    if( rc!=SQLITE_OK ){
      /* If an error occurred in findInodeInfo(), close the file descriptor
      ** immediately, before releasing the mutex. findInodeInfo() may fail
      ** in two scenarios:







>
>
>
>







 







>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







>
>
>







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>







1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
....
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
....
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
....
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
....
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
....
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
....
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
#if SQLITE_ENABLE_LOCKING_STYLE
  unsigned long long sharedByte;  /* for AFP simulated shared lock */
#endif
#if OS_VXWORKS
  sem_t *pSem;                    /* Named POSIX semaphore */
  char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
#endif
#ifdef SQLITE_SHARED_MAPPING
  sqlite3_int64 nSharedMapping;   /* Size of mapped region in bytes */
  void *pSharedMapping;           /* Memory mapped region */
#endif
};

/*
** A lists of all unixInodeInfo objects.
*/
static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
static unsigned int nUnusedFd = 0;    /* Total unused file descriptors */
................................................................................
static void releaseInodeInfo(unixFile *pFile){
  unixInodeInfo *pInode = pFile->pInode;
  assert( unixMutexHeld() );
  if( ALWAYS(pInode) ){
    pInode->nRef--;
    if( pInode->nRef==0 ){
      assert( pInode->pShmNode==0 );
#ifdef SQLITE_SHARED_MAPPING
      if( pInode->pSharedMapping ){
        osMunmap(pInode->pSharedMapping, pInode->nSharedMapping);
        pInode->pSharedMapping = 0;
        pInode->nSharedMapping = 0;
      }
#endif
      closePendingFds(pFile);
      if( pInode->pPrev ){
        assert( pInode->pPrev->pNext==pInode );
        pInode->pPrev->pNext = pInode->pNext;
      }else{
        assert( inodeList==pInode );
        inodeList = pInode->pNext;
................................................................................
  return SQLITE_OK;
}

/*
** Close the file.
*/
static int nolockClose(sqlite3_file *id) {
#ifdef SQLITE_SHARED_MAPPING
  unixFile *pFd = (unixFile*)id;
  if( pFd->pInode ){
    unixEnterMutex();
    releaseInodeInfo(pFd);
    unixLeaveMutex();
  }
#endif
  return closeUnixFile(id);
}

/******************* End of the no-op lock implementation *********************
******************************************************************************/

/******************************************************************************
................................................................................
      if( newLimit>0 && sizeof(size_t)<8 ){
        newLimit = (newLimit & 0x7FFFFFFF);
      }

      *(i64*)pArg = pFile->mmapSizeMax;
      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
        pFile->mmapSizeMax = newLimit;
#ifdef SQLITE_SHARED_MAPPING
        if( pFile->pInode==0 )
#endif
        if( pFile->mmapSize>0 ){
          unixUnmapfile(pFile);
          rc = unixMapfile(pFile, -1);
        }
      }
      return rc;
    }
................................................................................

#if SQLITE_MAX_MMAP_SIZE>0
/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
  assert( pFd->nFetchOut==0 );
#ifdef SQLITE_SHARED_MAPPING
  if( pFd->pInode ) return;
#endif
  if( pFd->pMapRegion ){
    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
    pFd->pMapRegion = 0;
    pFd->mmapSize = 0;
    pFd->mmapSizeActual = 0;
  }
}
................................................................................
      return SQLITE_IOERR_FSTAT;
    }
    nMap = statbuf.st_size;
  }
  if( nMap>pFd->mmapSizeMax ){
    nMap = pFd->mmapSizeMax;
  }

#ifdef SQLITE_SHARED_MAPPING
  if( pFd->pInode ){
    unixInodeInfo *pInode = pFd->pInode;
    if( pFd->pMapRegion ) return SQLITE_OK;
    unixEnterMutex();
    if( pInode->pSharedMapping==0 ){
      u8 *pNew = osMmap(0, nMap, PROT_READ, MAP_SHARED, pFd->h, 0);
      if( pNew==MAP_FAILED ){
        unixLogError(SQLITE_OK, "mmap", pFd->zPath);
        pFd->mmapSizeMax = 0;
      }else{
        pInode->pSharedMapping = pNew;
        pInode->nSharedMapping = nMap;
      }
    }
    pFd->pMapRegion = pInode->pSharedMapping;
    pFd->mmapSizeActual = pFd->mmapSize = pInode->nSharedMapping;
    unixLeaveMutex();
    return SQLITE_OK;
  }
#endif

  assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
  if( nMap!=pFd->mmapSize ){
    unixRemapfile(pFd, nMap);
  }

  return SQLITE_OK;
................................................................................
#endif
  }

  if( pLockingStyle == &posixIoMethods
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
    || pLockingStyle == &nfsIoMethods
#endif
#ifdef SQLITE_SHARED_MAPPING
    || pLockingStyle == &nolockIoMethods
#endif
  ){
    unixEnterMutex();
    rc = findInodeInfo(pNew, &pNew->pInode);
    if( rc!=SQLITE_OK ){
      /* If an error occurred in findInodeInfo(), close the file descriptor
      ** immediately, before releasing the mutex. findInodeInfo() may fail
      ** in two scenarios: