From: dan Date: Mon, 14 Jun 2010 16:16:33 +0000 (+0000) Subject: Add the new xShmMap (formerly xShmPage) to os_win.c. X-Git-Tag: version-3.7.2~275^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9785fc9510ac710fc15f4e6a5e4012de48a47c98;p=thirdparty%2Fsqlite.git Add the new xShmMap (formerly xShmPage) to os_win.c. FossilOrigin-Name: 13e7a8242206bca4b5bf356ef074e66474d39609 --- diff --git a/manifest b/manifest index b211bcfee4..86656a4e33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sxShmGet/Size/Release\sfrom\sthe\ssqlite3_vfs\sstructure.\sChange\sthe\sname\sof\sxShmPage\sto\sxShmMap.\sRemove\ssome\scode\sthat\sis\snow\sunused\sfrom\sos_unix.c\sand\ssome\sof\sthe\stest\sVFS\simplementations. -D 2010-06-14T14:07:51 +C Add\sthe\snew\sxShmMap\s(formerly\sxShmPage)\sto\sos_win.c. +D 2010-06-14T16:16:34 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -154,8 +154,8 @@ F src/os.c 9c4a2f82a50306a33907678ec0187b6ad1486bfe F src/os.h d7775504a51e6e0d40315aa427b3e229ff9ff9ca F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19 -F src/os_unix.c 0a57b86241011ca25f2fb83e4825b7af7fe6d920 -F src/os_win.c 0cf1f571546f165001e2391b5d4a4a16d86977d3 +F src/os_unix.c 710418915cc3b59e596ee7ae916deca5dc740ca7 +F src/os_win.c 3d761e33687cb24645fe66e5efd11244390e8e9c F src/pager.c 2964185d4356d0dc159b8340e52d2538d32394e5 F src/pager.h ca1f23c0cf137ac26f8908df2427c8b308361efd F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e @@ -820,7 +820,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1ce9c92bffa5d7f8431c005b29d698b0f5b95875 -R 8ee76bbe532e6db3f47bf2104ddf1a48 +P fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc +R 25e35232d2e784a0633c25f463199a04 U dan -Z 95a9a1111fae03b142846d91ecde0c57 +Z 06f3bcfd0aba7d97df7e9b4406c194ab diff --git a/manifest.uuid b/manifest.uuid index 6a3db6fb58..13f5f78d56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc \ No newline at end of file +13e7a8242206bca4b5bf356ef074e66474d39609 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 22c9a92826..fcccead725 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3573,7 +3573,7 @@ static void unixShmBarrier( ** address space (if it is not already), *pp is set to point to the mapped ** memory and SQLITE_OK returned. */ -static int unixShmPage( +static int unixShmMap( sqlite3_file *fd, /* Handle open on database file */ int iRegion, /* Region to retrieve */ int szRegion, /* Size of regions */ @@ -3655,7 +3655,7 @@ shmpage_out: # define unixShmLock 0 # define unixShmBarrier 0 # define unixShmClose 0 -# define unixShmPage 0 +# define unixShmMap 0 #endif /* #ifndef SQLITE_OMIT_WAL */ /* @@ -3717,7 +3717,7 @@ static const sqlite3_io_methods METHOD = { \ unixShmLock, /* xShmLock */ \ unixShmBarrier, /* xShmBarrier */ \ unixShmClose, /* xShmClose */ \ - unixShmPage /* xShmPage */ \ + unixShmMap /* xShmMap */ \ }; \ static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ diff --git a/src/os_win.c b/src/os_win.c index 1a9994b08d..3a6b47771a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1216,13 +1216,17 @@ static int winShmMutexHeld(void) { */ struct winShmNode { sqlite3_mutex *mutex; /* Mutex to access this object */ - sqlite3_mutex *mutexBuf; /* Mutex to access zBuf[] */ char *zFilename; /* Name of the file */ winFile hFile; /* File handle from winOpen */ - HANDLE hMap; /* File handle from CreateFileMapping */ + + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; DWORD lastErrno; /* The Windows errno from the last I/O error */ - int szMap; /* Size of the mapping of file into memory */ - char *pMMapBuf; /* Where currently mmapped(). NULL if unmapped */ + int nRef; /* Number of winShm objects pointing to this */ winShm *pFirst; /* All winShm objects pointing to this */ winShmNode *pNext; /* Next in list of all winShmNode objects */ @@ -1325,19 +1329,18 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ pp = &winShmNodeList; while( (p = *pp)!=0 ){ if( p->nRef==0 ){ + int i; if( p->mutex ) sqlite3_mutex_free(p->mutex); - if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf); - if( p->pMMapBuf ){ - UnmapViewOfFile(p->pMMapBuf); - } - if( INVALID_HANDLE_VALUE != p->hMap ){ - CloseHandle(p->hMap); + for(i=0; inRegion; i++){ + UnmapViewOfFile(p->aRegion[i].pMap); + CloseHandle(p->aRegion[i].hMap); } if( p->hFile.h != INVALID_HANDLE_VALUE ) { winClose((sqlite3_file *)&p->hFile); } if( deleteFlag ) winDelete(pVfs, p->zFilename, 0); *pp = p->pNext; + sqlite3_free(p->aRegion); sqlite3_free(p); }else{ pp = &p->pNext; @@ -1404,8 +1407,6 @@ static int winShmOpen( }else{ pShmNode = pNew; pNew = 0; - pShmNode->pMMapBuf = NULL; - pShmNode->hMap = INVALID_HANDLE_VALUE; ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; @@ -1415,11 +1416,6 @@ static int winShmOpen( rc = SQLITE_NOMEM; goto shm_open_err; } - pShmNode->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutexBuf==0 ){ - rc = SQLITE_NOMEM; - goto shm_open_err; - } rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, /* Name of the file (UTF-8) */ (sqlite3_file*)&pShmNode->hFile, /* File handle here */ @@ -1507,171 +1503,113 @@ static int winShmClose( } /* -** Increase the size of the underlying storage for a shared-memory segment. +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. ** -** The reqSize parameter is the new requested minimum size of the underlying -** shared memory. This routine may choose to make the shared memory larger -** than this value (for example to round the shared memory size up to an -** operating-system dependent page size.) +** If an error occurs, an error code is returned and *pp is set to NULL. ** -** This routine will only grow the size of shared memory. A request for -** a smaller size is a no-op. -*/ -static int winShmSize( - sqlite3_file *fd, /* Database holding the shared memory */ - int reqSize, /* Requested size. -1 for query only */ - int *pNewSize /* Write new size here */ +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ ){ winFile *pDbFd = (winFile*)fd; winShm *p = pDbFd->pShm; winShmNode *pShmNode = p->pShmNode; int rc = SQLITE_OK; - *pNewSize = 0; - if( reqSize>=0 ){ - sqlite3_int64 sz; - rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); - if( SQLITE_OK==rc && reqSize>sz ){ - rc = winTruncate((sqlite3_file *)&pShmNode->hFile, reqSize); - } - } - if( SQLITE_OK==rc ){ - sqlite3_int64 sz; + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + + if( pShmNode->nRegion<=iRegion ){ + struct ShmRegion *apNew; /* New aRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); - if( SQLITE_OK==rc ){ - *pNewSize = (int)sz; - }else{ - rc = SQLITE_IOERR; + if( rc!=SQLITE_OK ){ + goto shmpage_out; } - } - return rc; -} + if( szhFile, nByte); + if( rc!=SQLITE_OK ){ + goto shmpage_out; + } + } -/* -** Map the shared storage into memory. The minimum size of the -** mapping should be reqMapSize if reqMapSize is positive. If -** reqMapSize is zero or negative, the implementation can choose -** whatever mapping size is convenient. -** -** *ppBuf is made to point to the memory which is a mapping of the -** underlying storage. A mutex is acquired to prevent other threads -** from running while *ppBuf is in use in order to prevent other threads -** remapping *ppBuf out from under this thread. The winShmRelease() -** call will release the mutex. However, if the lock state is CHECKPOINT, -** the mutex is not acquired because CHECKPOINT will never remap the -** buffer. RECOVER might remap, though, so CHECKPOINT will acquire -** the mutex if and when it promotes to RECOVER. -** -** RECOVER needs to be atomic. The same mutex that prevents *ppBuf from -** being remapped also prevents more than one thread from being in -** RECOVER at a time. But, RECOVER sometimes wants to remap itself. -** To prevent RECOVER from losing its lock while remapping, the -** mutex is not released by winShmRelease() when in RECOVER. -** -** *pNewMapSize is set to the size of the mapping. -** -** *ppBuf and *pNewMapSize might be NULL and zero if no space has -** yet been allocated to the underlying storage. -*/ -static int winShmGet( - sqlite3_file *fd, /* The database file holding the shared memory */ - int reqMapSize, /* Requested size of mapping. -1 means don't care */ - int *pNewMapSize, /* Write new size of mapping here */ - void volatile **ppBuf /* Write mapping buffer origin here */ -){ - winFile *pDbFd = (winFile*)fd; - winShm *p = pDbFd->pShm; - winShmNode *pShmNode = p->pShmNode; - int rc = SQLITE_OK; - - if( p->hasMutexBuf==0 ){ - assert( sqlite3_mutex_notheld(pShmNode->mutex) ); - sqlite3_mutex_enter(pShmNode->mutexBuf); - p->hasMutexBuf = 1; - } - sqlite3_mutex_enter(pShmNode->mutex); - if( pShmNode->szMap==0 || reqMapSize>pShmNode->szMap ){ - int actualSize; - if( winShmSize(fd, -1, &actualSize)==SQLITE_OK - && reqMapSizeaRegion, (iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM; + goto shmpage_out; } - if( pShmNode->pMMapBuf ){ - if( !UnmapViewOfFile(pShmNode->pMMapBuf) ){ + pShmNode->aRegion = apNew; + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + + hMap = CreateFileMapping(pShmNode->hFile.h, + NULL, PAGE_READWRITE, 0, nByte, NULL + ); + if( hMap ){ + pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, + 0, 0, nByte + ); + } + if( !pMap ){ pShmNode->lastErrno = GetLastError(); rc = SQLITE_IOERR; + if( hMap ) CloseHandle(hMap); + goto shmpage_out; } - CloseHandle(pShmNode->hMap); - pShmNode->hMap = INVALID_HANDLE_VALUE; - } - if( SQLITE_OK == rc ){ - pShmNode->pMMapBuf = 0; - if( reqMapSize == 0 ){ - /* can't create 0 byte file mapping in Windows */ - pShmNode->szMap = 0; - }else{ - /* create the file mapping object */ - if( INVALID_HANDLE_VALUE == pShmNode->hMap ){ - /* TBD provide an object name to each file - ** mapping so it can be re-used across processes. - */ - pShmNode->hMap = CreateFileMapping(pShmNode->hFile.h, - NULL, - PAGE_READWRITE, - 0, - reqMapSize, - NULL); - } - if( NULL==pShmNode->hMap ){ - pShmNode->lastErrno = GetLastError(); - rc = SQLITE_IOERR; - pShmNode->szMap = 0; - pShmNode->hMap = INVALID_HANDLE_VALUE; - }else{ - pShmNode->pMMapBuf = MapViewOfFile(pShmNode->hMap, - FILE_MAP_WRITE | FILE_MAP_READ, - 0, - 0, - reqMapSize); - if( !pShmNode->pMMapBuf ){ - pShmNode->lastErrno = GetLastError(); - rc = SQLITE_IOERR; - pShmNode->szMap = 0; - }else{ - pShmNode->szMap = reqMapSize; - } - } - } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; } } - *pNewMapSize = pShmNode->szMap; - *ppBuf = pShmNode->pMMapBuf; - sqlite3_mutex_leave(pShmNode->mutex); - return rc; -} -/* -** Release the lock held on the shared memory segment so that other -** threads are free to resize it if necessary. -** -** If the lock is not currently held, this routine is a harmless no-op. -** -** If the shared-memory object is in lock state RECOVER, then we do not -** really want to release the lock, so in that case too, this routine -** is a no-op. -*/ -static int winShmRelease(sqlite3_file *fd){ - winFile *pDbFd = (winFile*)fd; - winShm *p = pDbFd->pShm; - if( p->hasMutexBuf ){ - winShmNode *pShmNode = p->pShmNode; - assert( sqlite3_mutex_notheld(pShmNode->mutex) ); - sqlite3_mutex_leave(pShmNode->mutexBuf); - p->hasMutexBuf = 0; +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iRegion*szRegion]; + }else{ + *pp = 0; } - return SQLITE_OK; + sqlite3_mutex_leave(pShmNode->mutex); + return rc; } /* @@ -1756,12 +1694,10 @@ static const sqlite3_io_methods winIoMethod = { winSectorSize, winDeviceCharacteristics, winShmOpen, /* xShmOpen */ - winShmSize, /* xShmSize */ - winShmGet, /* xShmGet */ - winShmRelease, /* xShmRelease */ winShmLock, /* xShmLock */ winShmBarrier, /* xShmBarrier */ - winShmClose /* xShmClose */ + winShmClose, /* xShmClose */ + winShmMap /* xShmMap */ }; /***************************************************************************