/ Changes On Branch winPreCache
Login

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

Changes In Branch winPreCache Excluding Merge-Ins

This is equivalent to a diff from a41d2969 to 360c0fd1

2014-05-09
11:15
Add new static mutex SQLITE_MUTEX_STATIC_APP3. (check-in: ee0ab09c user: dan tags: threads)
00:36
Fix several harmless compiler warnings. (Closed-Leaf check-in: 360c0fd1 user: mistachkin tags: winPreCache)
2014-05-08
22:15
Fix typos in logging code. (check-in: dc7f84df user: mistachkin tags: winPreCache)
22:01
Experimental changes to pre-cache a database file prior to it being fully opened. (check-in: 38cbcedb user: mistachkin tags: winPreCache)
22:01
Fix static variable declaration issue on Windows. (check-in: a41d2969 user: mistachkin tags: threads)
2014-05-06
16:21
Add a little extra variety to the tests in sort4.test. (check-in: 7de6aee6 user: dan tags: threads)

Changes to src/os_win.c.

   263    263     int nFetchOut;                /* Number of outstanding xFetch references */
   264    264     HANDLE hMap;                  /* Handle for accessing memory mapping */
   265    265     void *pMapRegion;             /* Area memory mapped */
   266    266     sqlite3_int64 mmapSize;       /* Usable size of mapped region */
   267    267     sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
   268    268     sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
   269    269   #endif
          270  +  SQLiteThread *preCacheThread; /* Thread used to pre-cache file contents */
   270    271   };
   271    272   
   272    273   /*
   273    274   ** Allowed values for winFile.ctrlFlags
   274    275   */
   275    276   #define WINFILE_RDONLY          0x02   /* Connection is read only */
   276    277   #define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
................................................................................
  1040   1041   #else
  1041   1042     { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
  1042   1043   #endif
  1043   1044   
  1044   1045   #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
  1045   1046           LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
  1046   1047   
         1048  +  { "DuplicateHandle",          (SYSCALL)DuplicateHandle,        0 },
         1049  +
         1050  +#define osDuplicateHandle ((BOOL(WINAPI*)(HANDLE, \
         1051  +        HANDLE,HANDLE,LPHANDLE,DWORD,BOOL,DWORD))aSyscall[76].pCurrent)
         1052  +
  1047   1053   }; /* End of the overrideable system calls */
  1048   1054   
  1049   1055   /*
  1050   1056   ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
  1051   1057   ** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
  1052   1058   ** system call pointer, or SQLITE_NOTFOUND if there is no configurable
  1053   1059   ** system call named zName.
................................................................................
  2349   2355   
  2350   2356     assert( id!=0 );
  2351   2357   #ifndef SQLITE_OMIT_WAL
  2352   2358     assert( pFile->pShm==0 );
  2353   2359   #endif
  2354   2360     assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
  2355   2361     OSTRACE(("CLOSE file=%p\n", pFile->h));
         2362  +
         2363  +#if SQLITE_MAX_WORKER_THREADS>0
         2364  +  if( pFile->preCacheThread ){
         2365  +    void *pOut = 0;
         2366  +    sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
         2367  +  }
         2368  +#endif
  2356   2369   
  2357   2370   #if SQLITE_MAX_MMAP_SIZE>0
  2358   2371     winUnmapfile(pFile);
  2359   2372   #endif
  2360   2373   
  2361   2374     do{
  2362   2375       rc = osCloseHandle(pFile->h);
................................................................................
  3193   3206   ** Return a vector of device characteristics.
  3194   3207   */
  3195   3208   static int winDeviceCharacteristics(sqlite3_file *id){
  3196   3209     winFile *p = (winFile*)id;
  3197   3210     return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
  3198   3211            ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
  3199   3212   }
         3213  +
         3214  +#if SQLITE_MAX_WORKER_THREADS>0
         3215  +/*
         3216  +** Thread routine that attempts to read the entire file.  This is used to
         3217  +** provide a hint to the operating system that the entire file should be held
         3218  +** in the cache.
         3219  +*/
         3220  +static void *winPreCacheThread(void *pCtx){
         3221  +  winFile *pFile = (winFile*)pCtx;
         3222  +  void *pBuf = 0;
         3223  +  DWORD lastErrno;
         3224  +  HANDLE dupHandle = NULL;
         3225  +  DWORD dwSize, dwRet;
         3226  +  DWORD dwAmt;
         3227  +  DWORD nRead;
         3228  +
         3229  +  if( !osDuplicateHandle(GetCurrentProcess(), pFile->h, GetCurrentProcess(),
         3230  +                         &dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ){
         3231  +    pFile->lastErrno = osGetLastError();
         3232  +    OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR\n", dupHandle));
         3233  +    return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR, pFile->lastErrno,
         3234  +                                         "winPreCacheThread1", pFile->zPath));
         3235  +  }
         3236  +  dwSize = osSetFilePointer(dupHandle, 0, 0, FILE_END);
         3237  +  if( (dwSize==INVALID_SET_FILE_POINTER
         3238  +      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
         3239  +    pFile->lastErrno = lastErrno;
         3240  +    osCloseHandle(dupHandle);
         3241  +    OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
         3242  +    return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
         3243  +                                         "winPreCacheThread2", pFile->zPath));
         3244  +  }
         3245  +  dwRet = osSetFilePointer(dupHandle, 0, 0, FILE_BEGIN);
         3246  +  if( (dwRet==INVALID_SET_FILE_POINTER
         3247  +      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
         3248  +    pFile->lastErrno = lastErrno;
         3249  +    osCloseHandle(dupHandle);
         3250  +    OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
         3251  +    return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
         3252  +                                         "winPreCacheThread3", pFile->zPath));
         3253  +  }
         3254  +  dwAmt = 4194304; /* TODO: Tuning. */
         3255  +  if( dwSize<dwAmt ){
         3256  +    dwAmt = dwSize;
         3257  +  }
         3258  +  pBuf = sqlite3MallocZero( dwAmt );
         3259  +  if( pBuf==0 ){
         3260  +    osCloseHandle(dupHandle);
         3261  +    OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_NOMEM\n", dupHandle));
         3262  +    return SQLITE_INT_TO_PTR(SQLITE_IOERR_NOMEM);
         3263  +  }
         3264  +  while( 1 ){
         3265  +    if( !osReadFile(dupHandle, pBuf, dwAmt, &nRead, 0) ){
         3266  +      pFile->lastErrno = osGetLastError();
         3267  +      sqlite3_free(pBuf);
         3268  +      osCloseHandle(dupHandle);
         3269  +      OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_READ\n", dupHandle));
         3270  +      return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
         3271  +                                           "winPreCacheThread4", pFile->zPath));
         3272  +    }
         3273  +    if( nRead<dwAmt ){
         3274  +      sqlite3_free(pBuf);
         3275  +      osCloseHandle(dupHandle);
         3276  +      OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SHORT_READ\n", dupHandle));
         3277  +      return SQLITE_INT_TO_PTR(winLogError(SQLITE_IOERR_SHORT_READ,
         3278  +                                           pFile->lastErrno,
         3279  +                                           "winPreCacheThread5", pFile->zPath));
         3280  +    }
         3281  +    dwSize -= dwAmt;
         3282  +    if( dwSize==0 ){
         3283  +      break;
         3284  +    }
         3285  +  }
         3286  +  sqlite3_free(pBuf);
         3287  +  osCloseHandle(dupHandle);
         3288  +  return SQLITE_INT_TO_PTR(SQLITE_OK);
         3289  +}
         3290  +#endif
  3200   3291   
  3201   3292   /* 
  3202   3293   ** Windows will only let you create file view mappings
  3203   3294   ** on allocation size granularity boundaries.
  3204   3295   ** During sqlite3_os_init() we do a GetSystemInfo()
  3205   3296   ** to get the granularity size.
  3206   3297   */
................................................................................
  4700   4791   #if SQLITE_MAX_MMAP_SIZE>0
  4701   4792     pFile->hMap = NULL;
  4702   4793     pFile->pMapRegion = 0;
  4703   4794     pFile->mmapSize = 0;
  4704   4795     pFile->mmapSizeActual = 0;
  4705   4796     pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
  4706   4797   #endif
         4798  +#if SQLITE_MAX_WORKER_THREADS>0
         4799  +  sqlite3ThreadCreate(&pFile->preCacheThread, winPreCacheThread, pFile);
         4800  +
         4801  +  {
         4802  +    void *pOut = 0;
         4803  +    sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
         4804  +    pFile->preCacheThread = 0;
         4805  +  }
         4806  +#endif
  4707   4807   
  4708   4808     OpenCounter(+1);
  4709   4809     return rc;
  4710   4810   }
  4711   4811   
  4712   4812   /*
  4713   4813   ** Delete the named file.
................................................................................
  5418   5518       winGetSystemCall,    /* xGetSystemCall */
  5419   5519       winNextSystemCall,   /* xNextSystemCall */
  5420   5520     };
  5421   5521   #endif
  5422   5522   
  5423   5523     /* Double-check that the aSyscall[] array has been constructed
  5424   5524     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  5425         -  assert( ArraySize(aSyscall)==76 );
         5525  +  assert( ArraySize(aSyscall)==77 );
  5426   5526   
  5427   5527     /* get memory map allocation granularity */
  5428   5528     memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
  5429   5529   #if SQLITE_OS_WINRT
  5430   5530     osGetNativeSystemInfo(&winSysInfo);
  5431   5531   #else
  5432   5532     osGetSystemInfo(&winSysInfo);