Add the new xShmMap (formerly xShmPage) to os_win.c.

FossilOrigin-Name: 13e7a8242206bca4b5bf356ef074e66474d39609
This commit is contained in:
dan
2010-06-14 16:16:33 +00:00
parent 188019153d
commit 9785fc9510
4 changed files with 115 additions and 179 deletions
+7 -7
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc
13e7a8242206bca4b5bf356ef074e66474d39609
+3 -3
View File
@@ -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); \
+104 -168
View File
@@ -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; i<p->nRegion; 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,173 +1503,115 @@ 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.
** 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 winShmSize(
sqlite3_file *fd, /* Database holding the shared memory */
int reqSize, /* Requested size. -1 for query only */
int *pNewSize /* Write new size here */
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;
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
if( SQLITE_OK==rc ){
*pNewSize = (int)sz;
}else{
rc = SQLITE_IOERR;
}
}
return rc;
}
/*
** 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
&& reqMapSize<actualSize
){
reqMapSize = actualSize;
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( rc!=SQLITE_OK ){
goto shmpage_out;
}
if( pShmNode->pMMapBuf ){
if( !UnmapViewOfFile(pShmNode->pMMapBuf) ){
if( sz<nByte ){
/* The requested memory region does not exist. If isWrite is set to
** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
**
** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
** the requested memory region.
*/
if( !isWrite ) goto shmpage_out;
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
if( rc!=SQLITE_OK ){
goto shmpage_out;
}
}
/* Map the requested memory region into this processes address space. */
apNew = (struct ShmRegion *)sqlite3_realloc(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
rc = SQLITE_IOERR_NOMEM;
goto shmpage_out;
}
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;
shmpage_out:
if( pShmNode->nRegion>iRegion ){
char *p = (char *)pShmNode->aRegion[iRegion].pMap;
*pp = (void *)&p[iRegion*szRegion];
}else{
*pp = 0;
}
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;
}
return SQLITE_OK;
}
/*
** Change the lock state for a shared-memory segment.
*/
@@ -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 */
};
/***************************************************************************