mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Attempt to emulate mremap() on non-Linux systems by allocating a second mapping immediately following the first in virtual memory.
FossilOrigin-Name: 4d67433db8fb4754ae6b192945e479f3d7bad579
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\sxFetch\sand\sxUnfetch\smethods\sto\sthe\sos_win.c\sVFS.
|
C Attempt\sto\semulate\smremap()\son\snon-Linux\ssystems\sby\sallocating\sa\ssecond\smapping\simmediately\sfollowing\sthe\sfirst\sin\svirtual\smemory.
|
||||||
D 2013-04-01T17:22:51.830
|
D 2013-04-01T17:56:59.408
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7
|
F Makefile.in df3e48659d80e1b7765785d8d66c86b320f72cc7
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -160,7 +160,7 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
|
|||||||
F src/os.c 809d0707cec693e1b9b376ab229271ad74c3d35d
|
F src/os.c 809d0707cec693e1b9b376ab229271ad74c3d35d
|
||||||
F src/os.h ae08bcc5f6ec6b339f4a2adf3931bb88cc14c3e4
|
F src/os.h ae08bcc5f6ec6b339f4a2adf3931bb88cc14c3e4
|
||||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||||
F src/os_unix.c d6981218583748080374ed98a03f6a87e2bdc9e0
|
F src/os_unix.c d136eca0cff2f8a5ac2f45867d5e5153d60e377c
|
||||||
F src/os_win.c f705e7ce230f86104dedcc2987a21d564b236659
|
F src/os_win.c f705e7ce230f86104dedcc2987a21d564b236659
|
||||||
F src/pager.c 2b9980e87296812a6ce51121a3335550ae25e3ec
|
F src/pager.c 2b9980e87296812a6ce51121a3335550ae25e3ec
|
||||||
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
F src/pager.h 5cb78b8e1adfd5451e600be7719f5a99d87ac3b1
|
||||||
@@ -1040,7 +1040,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
|
||||||
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
|
||||||
P a1040f0397d57855500926494c978623286ddc77
|
P a1653a257d6af6e8b10c819e68b12f6c2f485811
|
||||||
R 52b13f77704d4760e77e0cfd9ab57bff
|
R 144bfd1ec5d6fde06365c0d3ea4b879a
|
||||||
U drh
|
U dan
|
||||||
Z 878a27609130450cef13cc90a8feab48
|
Z 4e8a79b712821b5d3d9730a626894d79
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
a1653a257d6af6e8b10c819e68b12f6c2f485811
|
4d67433db8fb4754ae6b192945e479f3d7bad579
|
||||||
137
src/os_unix.c
137
src/os_unix.c
@@ -313,6 +313,17 @@ struct unixFile {
|
|||||||
#define threadid 0
|
#define threadid 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** HAVE_MREMAP defaults to true on Linux and false everywhere else.
|
||||||
|
*/
|
||||||
|
#if !defined(HAVE_MREMAP)
|
||||||
|
# if defined(__linux__) && defined(_GNU_SOURCE)
|
||||||
|
# define HAVE_MREMAP 1
|
||||||
|
# else
|
||||||
|
# define HAVE_MREMAP 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Different Unix systems declare open() in different ways. Same use
|
** Different Unix systems declare open() in different ways. Same use
|
||||||
** open(const char*,int,mode_t). Others use open(const char*,int,...).
|
** open(const char*,int,mode_t). Others use open(const char*,int,...).
|
||||||
@@ -450,7 +461,7 @@ static struct unix_syscall {
|
|||||||
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
{ "munmap", (sqlite3_syscall_ptr)munmap, 0 },
|
||||||
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
|
#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
|
||||||
|
|
||||||
#if defined(__linux__) && defined(_GNU_SOURCE)
|
#if HAVE_MREMAP
|
||||||
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
|
||||||
#else
|
#else
|
||||||
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
|
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
|
||||||
@@ -1124,7 +1135,6 @@ static int unixLogErrorAtLine(
|
|||||||
zErr = strerror(iErrno);
|
zErr = strerror(iErrno);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( errcode!=SQLITE_OK );
|
|
||||||
if( zPath==0 ) zPath = "";
|
if( zPath==0 ) zPath = "";
|
||||||
sqlite3_log(errcode,
|
sqlite3_log(errcode,
|
||||||
"os_unix.c:%d: (%d) %s(%s) - %s",
|
"os_unix.c:%d: (%d) %s(%s) - %s",
|
||||||
@@ -3619,7 +3629,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pFile->mmapLimit>0 ){
|
if( pFile->mmapLimit>0 && nByte>pFile->mmapSize ){
|
||||||
int rc;
|
int rc;
|
||||||
if( pFile->szChunk<=0 ){
|
if( pFile->szChunk<=0 ){
|
||||||
if( robust_ftruncate(pFile->h, nByte) ){
|
if( robust_ftruncate(pFile->h, nByte) ){
|
||||||
@@ -4518,6 +4528,104 @@ static void unixUnmapfile(unixFile *pFd){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the system page size.
|
||||||
|
*/
|
||||||
|
static int unixGetPagesize(void){
|
||||||
|
#if HAVE_MREMAP
|
||||||
|
return 512;
|
||||||
|
#elif _BSD_SOURCE
|
||||||
|
return getpagesize();
|
||||||
|
#else
|
||||||
|
return (int)sysconf(_SC_PAGESIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Attempt to set the size of the memory mapping maintained by file
|
||||||
|
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
|
||||||
|
**
|
||||||
|
** If successful, this function sets the following variables:
|
||||||
|
**
|
||||||
|
** unixFile.pMapRegion
|
||||||
|
** unixFile.mmapSize
|
||||||
|
** unixFile.mmapOrigsize
|
||||||
|
**
|
||||||
|
** If unsuccessful, an error message is logged via sqlite3_log() and
|
||||||
|
** the three variables above are zeroed. In this case SQLite should
|
||||||
|
** continue accessing the database using the xRead() and xWrite()
|
||||||
|
** methods.
|
||||||
|
*/
|
||||||
|
static void unixRemapfile(
|
||||||
|
unixFile *pFd, /* File descriptor object */
|
||||||
|
i64 nNew /* Required mapping size */
|
||||||
|
){
|
||||||
|
int h = pFd->h; /* File descriptor open on db file */
|
||||||
|
u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */
|
||||||
|
i64 nOrig = pFd->mmapOrigsize; /* Size of pOrig region in bytes */
|
||||||
|
u8 *pNew = 0; /* Location of new mapping */
|
||||||
|
int flags = PROT_READ; /* Flags to pass to mmap() */
|
||||||
|
|
||||||
|
assert( pFd->nFetchOut==0 );
|
||||||
|
assert( nNew>pFd->mmapSize );
|
||||||
|
assert( nNew<=pFd->mmapLimit );
|
||||||
|
assert( nNew>0 );
|
||||||
|
assert( pFd->mmapOrigsize>=pFd->mmapSize );
|
||||||
|
|
||||||
|
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
||||||
|
|
||||||
|
if( pOrig ){
|
||||||
|
const int szSyspage = unixGetPagesize();
|
||||||
|
i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
|
||||||
|
u8 *pReq = &pOrig[nReuse];
|
||||||
|
|
||||||
|
/* Unmap any pages of the existing mapping that cannot be reused. */
|
||||||
|
if( nReuse!=nOrig ){
|
||||||
|
osMunmap(pReq, nOrig-nReuse);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_MREMAP
|
||||||
|
pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
|
||||||
|
#else
|
||||||
|
pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
|
||||||
|
if( pNew!=MAP_FAILED ){
|
||||||
|
if( pNew!=pReq ){
|
||||||
|
osMunmap(pNew, nNew - nReuse);
|
||||||
|
pNew = MAP_FAILED;
|
||||||
|
}else{
|
||||||
|
pNew = pOrig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The attempt to extend the existing mapping failed. Free the existing
|
||||||
|
** mapping and set pNew to NULL so that the code below will create a
|
||||||
|
** new mapping from scratch. */
|
||||||
|
if( pNew==MAP_FAILED ){
|
||||||
|
pNew = 0;
|
||||||
|
osMunmap(pOrig, nReuse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If pNew is still NULL, try to create an entirely new mapping. */
|
||||||
|
if( pNew==0 ){
|
||||||
|
pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
|
||||||
|
if( pNew==MAP_FAILED ){
|
||||||
|
pNew = 0;
|
||||||
|
nNew = 0;
|
||||||
|
unixLogError(SQLITE_OK, "mmap", pFd->zPath);
|
||||||
|
|
||||||
|
/* If the mmap() above failed, assume that all subsequent mmap() calls
|
||||||
|
** will probably fail too. Fall back to using xRead/xWrite exclusively
|
||||||
|
** in this case. */
|
||||||
|
pFd->mmapLimit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pFd->pMapRegion = (void *)pNew;
|
||||||
|
pFd->mmapSize = pFd->mmapOrigsize = nNew;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Memory map or remap the file opened by file-descriptor pFd (if the file
|
** Memory map or remap the file opened by file-descriptor pFd (if the file
|
||||||
** is already mapped, the existing mapping is replaced by the new). Or, if
|
** is already mapped, the existing mapping is replaced by the new). Or, if
|
||||||
@@ -4554,28 +4662,11 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( nMap!=pFd->mmapSize ){
|
if( nMap!=pFd->mmapSize ){
|
||||||
void *pNew = 0;
|
if( nMap>0 ){
|
||||||
|
unixRemapfile(pFd, nMap);
|
||||||
#if defined(__linux__) && defined(_GNU_SOURCE)
|
}else{
|
||||||
if( pFd->pMapRegion && nMap>0 ){
|
|
||||||
pNew = osMremap(pFd->pMapRegion, pFd->mmapOrigsize, nMap, MREMAP_MAYMOVE);
|
|
||||||
}else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
unixUnmapfile(pFd);
|
unixUnmapfile(pFd);
|
||||||
if( nMap>0 ){
|
|
||||||
int flags = PROT_READ;
|
|
||||||
if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
|
|
||||||
pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pNew==MAP_FAILED ){
|
|
||||||
return SQLITE_IOERR_MMAP;
|
|
||||||
}
|
|
||||||
pFd->pMapRegion = pNew;
|
|
||||||
pFd->mmapSize = nMap;
|
|
||||||
pFd->mmapOrigsize = nMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user