/ 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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  1111   1111   #if SQLITE_ENABLE_LOCKING_STYLE
  1112   1112     unsigned long long sharedByte;  /* for AFP simulated shared lock */
  1113   1113   #endif
  1114   1114   #if OS_VXWORKS
  1115   1115     sem_t *pSem;                    /* Named POSIX semaphore */
  1116   1116     char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
  1117   1117   #endif
         1118  +#ifdef SQLITE_SHARED_MAPPING
         1119  +  sqlite3_int64 nSharedMapping;   /* Size of mapped region in bytes */
         1120  +  void *pSharedMapping;           /* Memory mapped region */
         1121  +#endif
  1118   1122   };
  1119   1123   
  1120   1124   /*
  1121   1125   ** A lists of all unixInodeInfo objects.
  1122   1126   */
  1123   1127   static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
  1124   1128   static unsigned int nUnusedFd = 0;    /* Total unused file descriptors */
................................................................................
  1245   1249   static void releaseInodeInfo(unixFile *pFile){
  1246   1250     unixInodeInfo *pInode = pFile->pInode;
  1247   1251     assert( unixMutexHeld() );
  1248   1252     if( ALWAYS(pInode) ){
  1249   1253       pInode->nRef--;
  1250   1254       if( pInode->nRef==0 ){
  1251   1255         assert( pInode->pShmNode==0 );
         1256  +#ifdef SQLITE_SHARED_MAPPING
         1257  +      if( pInode->pSharedMapping ){
         1258  +        osMunmap(pInode->pSharedMapping, pInode->nSharedMapping);
         1259  +        pInode->pSharedMapping = 0;
         1260  +        pInode->nSharedMapping = 0;
         1261  +      }
         1262  +#endif
  1252   1263         closePendingFds(pFile);
  1253   1264         if( pInode->pPrev ){
  1254   1265           assert( pInode->pPrev->pNext==pInode );
  1255   1266           pInode->pPrev->pNext = pInode->pNext;
  1256   1267         }else{
  1257   1268           assert( inodeList==pInode );
  1258   1269           inodeList = pInode->pNext;
................................................................................
  2051   2062     return SQLITE_OK;
  2052   2063   }
  2053   2064   
  2054   2065   /*
  2055   2066   ** Close the file.
  2056   2067   */
  2057   2068   static int nolockClose(sqlite3_file *id) {
         2069  +#ifdef SQLITE_SHARED_MAPPING
         2070  +  unixFile *pFd = (unixFile*)id;
         2071  +  if( pFd->pInode ){
         2072  +    unixEnterMutex();
         2073  +    releaseInodeInfo(pFd);
         2074  +    unixLeaveMutex();
         2075  +  }
         2076  +#endif
  2058   2077     return closeUnixFile(id);
  2059   2078   }
  2060   2079   
  2061   2080   /******************* End of the no-op lock implementation *********************
  2062   2081   ******************************************************************************/
  2063   2082   
  2064   2083   /******************************************************************************
................................................................................
  3870   3889         if( newLimit>0 && sizeof(size_t)<8 ){
  3871   3890           newLimit = (newLimit & 0x7FFFFFFF);
  3872   3891         }
  3873   3892   
  3874   3893         *(i64*)pArg = pFile->mmapSizeMax;
  3875   3894         if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
  3876   3895           pFile->mmapSizeMax = newLimit;
         3896  +#ifdef SQLITE_SHARED_MAPPING
         3897  +        if( pFile->pInode==0 )
         3898  +#endif
  3877   3899           if( pFile->mmapSize>0 ){
  3878   3900             unixUnmapfile(pFile);
  3879   3901             rc = unixMapfile(pFile, -1);
  3880   3902           }
  3881   3903         }
  3882   3904         return rc;
  3883   3905       }
................................................................................
  4770   4792   
  4771   4793   #if SQLITE_MAX_MMAP_SIZE>0
  4772   4794   /*
  4773   4795   ** If it is currently memory mapped, unmap file pFd.
  4774   4796   */
  4775   4797   static void unixUnmapfile(unixFile *pFd){
  4776   4798     assert( pFd->nFetchOut==0 );
         4799  +#ifdef SQLITE_SHARED_MAPPING
         4800  +  if( pFd->pInode ) return;
         4801  +#endif
  4777   4802     if( pFd->pMapRegion ){
  4778   4803       osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
  4779   4804       pFd->pMapRegion = 0;
  4780   4805       pFd->mmapSize = 0;
  4781   4806       pFd->mmapSizeActual = 0;
  4782   4807     }
  4783   4808   }
................................................................................
  4900   4925         return SQLITE_IOERR_FSTAT;
  4901   4926       }
  4902   4927       nMap = statbuf.st_size;
  4903   4928     }
  4904   4929     if( nMap>pFd->mmapSizeMax ){
  4905   4930       nMap = pFd->mmapSizeMax;
  4906   4931     }
         4932  +
         4933  +#ifdef SQLITE_SHARED_MAPPING
         4934  +  if( pFd->pInode ){
         4935  +    unixInodeInfo *pInode = pFd->pInode;
         4936  +    if( pFd->pMapRegion ) return SQLITE_OK;
         4937  +    unixEnterMutex();
         4938  +    if( pInode->pSharedMapping==0 ){
         4939  +      u8 *pNew = osMmap(0, nMap, PROT_READ, MAP_SHARED, pFd->h, 0);
         4940  +      if( pNew==MAP_FAILED ){
         4941  +        unixLogError(SQLITE_OK, "mmap", pFd->zPath);
         4942  +        pFd->mmapSizeMax = 0;
         4943  +      }else{
         4944  +        pInode->pSharedMapping = pNew;
         4945  +        pInode->nSharedMapping = nMap;
         4946  +      }
         4947  +    }
         4948  +    pFd->pMapRegion = pInode->pSharedMapping;
         4949  +    pFd->mmapSizeActual = pFd->mmapSize = pInode->nSharedMapping;
         4950  +    unixLeaveMutex();
         4951  +    return SQLITE_OK;
         4952  +  }
         4953  +#endif
  4907   4954   
  4908   4955     assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) );
  4909   4956     if( nMap!=pFd->mmapSize ){
  4910   4957       unixRemapfile(pFd, nMap);
  4911   4958     }
  4912   4959   
  4913   4960     return SQLITE_OK;
................................................................................
  5339   5386   #endif
  5340   5387     }
  5341   5388   
  5342   5389     if( pLockingStyle == &posixIoMethods
  5343   5390   #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
  5344   5391       || pLockingStyle == &nfsIoMethods
  5345   5392   #endif
         5393  +#ifdef SQLITE_SHARED_MAPPING
         5394  +    || pLockingStyle == &nolockIoMethods
         5395  +#endif
  5346   5396     ){
  5347   5397       unixEnterMutex();
  5348   5398       rc = findInodeInfo(pNew, &pNew->pInode);
  5349   5399       if( rc!=SQLITE_OK ){
  5350   5400         /* If an error occurred in findInodeInfo(), close the file descriptor
  5351   5401         ** immediately, before releasing the mutex. findInodeInfo() may fail
  5352   5402         ** in two scenarios: