Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch winSectorSize Excluding Merge-Ins
This is equivalent to a diff from 97914266 to 47beb55c
2017-01-18
| ||
23:12 | For Windows 8.x and higher, require the SQLITE_WIN32_WIN8_SECTOR_SIZE compile-time option in order to enable sector size determination. (Leaf check-in: 47beb55c user: mistachkin tags: winSectorSize) | |
19:36 | Improve and update comments. (check-in: 2dc16d34 user: mistachkin tags: winSectorSize) | |
2017-01-16
| ||
18:10 | Back out check-in [0b3174e0b1364c] and replace it with a better fix for \ticket [91e2e8ba6ff2e2] - a fix that does not cause the problem identified by ticket [7ffd1ca1d2ad4ec]. Add new test cases for both tickets. (check-in: 9b64af7b user: drh tags: trunk) | |
16:01 | Add test cases for tickets [91e2e8ba6ff2e2] and [7ffd1ca1d2ad4ec]. (check-in: 9d0dfe0b user: drh tags: automatic-index-affinity) | |
11:54 | An example showing how to improve performance of sqlite3VdbeSerialPut() using the GCC intrinsic function __builtin_bswap64(). (Leaf check-in: e42ed9b4 user: drh tags: builtin-bswap64) | |
2017-01-13
| ||
22:21 | Merge updates from trunk. (check-in: 8b42b8e3 user: mistachkin tags: winSectorSize) | |
18:24 | Fix a problem preventing resumption of RBU operations after recovering from a process or system failure that occurs during the incremental-checkpoint phase. (check-in: 97914266 user: dan tags: trunk) | |
12:53 | Fix the build for SQLITE_ENABLE_MEMORY_MANAGEMENT. (check-in: 8c85b8fd user: drh tags: trunk) | |
Changes to src/os_win.c.
︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 73 74 75 76 77 | must be defined." #endif /* ** Define the required Windows SDK version constants if they are not ** already available. */ #ifndef NTDDI_WIN8 # define NTDDI_WIN8 0x06020000 #endif #ifndef NTDDI_WINBLUE # define NTDDI_WINBLUE 0x06030000 #endif | > > > > > > > > | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | must be defined." #endif /* ** Define the required Windows SDK version constants if they are not ** already available. */ #ifndef _WIN32_WINNT_VISTA # define _WIN32_WINNT_VISTA 0x0600 #endif #ifndef _WIN32_WINNT_WIN8 # define _WIN32_WINNT_WIN8 0x0602 #endif #ifndef NTDDI_WIN8 # define NTDDI_WIN8 0x06020000 #endif #ifndef NTDDI_WINBLUE # define NTDDI_WINBLUE 0x06030000 #endif |
︙ | ︙ | |||
442 443 444 445 446 447 448 | static int winMemInit(void *pAppData); static void winMemShutdown(void *pAppData); const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ /* | | | | | | | > > > > > > | > > > > | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | static int winMemInit(void *pAppData); static void winMemShutdown(void *pAppData); const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ /* ** The following variables are (normally) set once and never change ** thereafter. They record the major and minor OS version and whether ** the operating system type is Win9x or WinNT. ** ** sqlite3_os_type = 0: Operating system type is unknown. ** sqlite3_os_type = 1: Operating system type is Win9x. ** sqlite3_os_type = 2: Operating system type is WinNT. ** ** For the major and minor versions, the following are the "well-known" ** operating system releases (i.e. the ones that are tested for): ** ** sqlite3_os_major.sqlite3_os_minor = 6.0 = Windows Vista ** sqlite3_os_major.sqlite3_os_minor = 6.2 = Windows 8 ** ** In order to facilitate testing on WinNT systems, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; LONG SQLITE_WIN32_VOLATILE sqlite3_os_major = 0; LONG SQLITE_WIN32_VOLATILE sqlite3_os_minor = 0; #else static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; static LONG SQLITE_WIN32_VOLATILE sqlite3_os_major = 0; static LONG SQLITE_WIN32_VOLATILE sqlite3_os_minor = 0; #endif #ifndef SYSCALL # define SYSCALL sqlite3_syscall_ptr #endif /* |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 | #else { "SetFilePointerEx", (SYSCALL)0, 0 }, #endif #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) | | > | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 | #else { "SetFilePointerEx", (SYSCALL)0, 0 }, #endif #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) #if SQLITE_OS_WINRT || (defined(SQLITE_WIN32_WIN8_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN8) { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, #else { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, #endif #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) |
︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 | { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) }; /* End of the overrideable system calls */ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "win32" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "DeviceIoControl", (SYSCALL)DeviceIoControl, 0 }, #else { "DeviceIoControl", (SYSCALL)0, 0 }, #endif #define osDeviceIoControl ((BOOL(WINAPI*)( \ HANDLE,DWORD,LPVOID,DWORD,LPVOID,DWORD,LPVOID, \ LPOVERLAPPED))aSyscall[80].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "GetVolumeInformationByHandleW", (SYSCALL)GetVolumeInformationByHandleW, 0 }, #else { "GetVolumeInformationByHandleW", (SYSCALL)0, 0 }, #endif #define osGetVolumeInformationByHandleW ((BOOL(WINAPI*)( \ HANDLE,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR, \ DWORD))aSyscall[81].pCurrent) #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && defined(_WIN32_WINNT) && \ _WIN32_WINNT >= _WIN32_WINNT_VISTA { "GetVolumeInformationW", (SYSCALL)GetVolumeInformationW, 0 }, #else { "GetVolumeInformationW", (SYSCALL)0, 0 }, #endif #define osGetVolumeInformationW ((BOOL(WINAPI*)( \ LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR, \ DWORD))aSyscall[82].pCurrent) }; /* End of the overrideable system calls */ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "win32" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable |
︙ | ︙ | |||
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 | # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ int sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT ** kernel. */ return 1; #elif SQLITE_WIN32_GETVERSIONEX | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < | < < < < < < < < < < | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 | # define osIsNT() (1) #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else # define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This following version checking macros should evaluate to non-zero only ** when running on Windows Vista (or higher) or Windows 8 (or higher). */ #if !SQLITE_WIN32_GETVERSIONEX # define osIsVistaPlus() (1) # define osIsWin8Plus() (1) #elif SQLITE_OS_WINCE # define osIsVistaPlus() (0) # define osIsWin8Plus() (0) #elif SQLITE_OS_WINRT # define osIsVistaPlus() (1) # define osIsWin8Plus() (1) #else # define osIsVistaPlus() (winGetVersionEx() && ((sqlite3_os_major>6) || \ ((sqlite3_os_major==6) && (sqlite3_os_minor>=0)))) # define osIsWin8Plus() (winGetVersionEx() && ((sqlite3_os_major>6) || \ ((sqlite3_os_major==6) && (sqlite3_os_minor>=2)))) #endif /* ** This function populates the Windows version information needed by this ** module. Use of the GetVersionExA or GetVersionExW function is required. ** The return value will be non-zero if version information was queried. */ #if SQLITE_WIN32_GETVERSIONEX static int winGetVersionEx(){ if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ #if defined(SQLITE_WIN32_HAS_ANSI) OSVERSIONINFOA sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExA(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); osInterlockedCompareExchange(&sqlite3_os_major, (LONG)sInfo.dwMajorVersion, 0); osInterlockedCompareExchange(&sqlite3_os_minor, (LONG)sInfo.dwMinorVersion, 0); return 1; #elif defined(SQLITE_WIN32_HAS_WIDE) OSVERSIONINFOW sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExW(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); osInterlockedCompareExchange(&sqlite3_os_major, (LONG)sInfo.dwMajorVersion, 0); osInterlockedCompareExchange(&sqlite3_os_minor, (LONG)sInfo.dwMinorVersion, 0); return 1; #endif } return 0; } #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ int sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT ** kernel. */ return 1; #elif SQLITE_WIN32_GETVERSIONEX winGetVersionEx(); return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #else /* ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are ** deprecated are always assumed to be based on the NT kernel. |
︙ | ︙ | |||
3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 | } #endif } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be ** larger for some devices. ** ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and its journal file) that the sector size will be the ** same for both. */ static int winSectorSize(sqlite3_file *id){ (void)id; return SQLITE_DEFAULT_SECTOR_SIZE; } /* ** Return a vector of device characteristics. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 | } #endif } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } /* ** Same-volume determination for versions of Windows prior to Windows 8 ** is untested, undocumented, and unsupported. All such code is omitted ** unless the SQLITE_WIN32_VISTA_SECTOR_SIZE define is set at compile-time, ** and that compile-time option is off by default and undocumented. The ** following code is for reference only. */ #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA /* ** This function attempts to determine if the specified file resides on the ** same volume as the corresponding root directory. If not, the specified ** file may be impacted by a hard link, symbolic link, or reparse point (e.g. ** junction). ** ** This function may return false even when the file is on the same volume ** as the corresponding root directory. This function may return true only ** when there is no doubt that the specified file is on the same volume as ** the corresponding root directory associated with the volume. */ static BOOL winIsOnSameVolume(winFile *pFile){ WCHAR zRoot[] = L"_:\\\0"; /* underscore will be drive letter */ DWORD dwFileVolumeSerialNumber = 0; DWORD dwRootVolumeSerialNumber = 0; if ( !osGetVolumeInformationByHandleW(pFile->h, NULL, 0, &dwFileVolumeSerialNumber, NULL, NULL, NULL, 0) ){ return FALSE; } zRoot[0] = (WCHAR)pFile->zPath[0]; /* 'A' to 'Z' only, upper/lower case */ if( !osGetVolumeInformationW(zRoot, NULL, 0, &dwRootVolumeSerialNumber, NULL, NULL, NULL, 0) ){ return FALSE; } return (dwFileVolumeSerialNumber == dwRootVolumeSerialNumber); } #endif /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be ** larger for some devices. ** ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and its journal file) that the sector size will be the ** same for both. */ static int winSectorSize(sqlite3_file *id){ #if defined(SQLITE_WIN32_WIN8_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_WIN8 if( osIsWin8Plus() ){ winFile *pFile = (winFile*)id; FILE_STORAGE_INFO info; memset(&info, 0, sizeof(FILE_STORAGE_INFO)); if( osGetFileInformationByHandleEx(pFile->h, FileStorageInfo, &info, sizeof(info)) ){ ULONG size = info.FileSystemEffectivePhysicalBytesPerSectorForAtomicity; OSTRACE(("SECTOR file=%p, size=%lu\n", pFile->h, size)); if( size>0 && size<=2147483647 ){ return (int)size; } }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize1", pFile->zPath); } } #endif /* ** Sector-size determination for versions of Windows prior to Windows 8 ** is untested, undocumented, and unsupported. All such code is omitted ** unless the SQLITE_WIN32_VISTA_SECTOR_SIZE define is set at compile-time, ** and that compile-time option is off by default and undocumented. The ** following code is for reference only. */ #if defined(SQLITE_WIN32_VISTA_SECTOR_SIZE) && \ defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA if( osIsVistaPlus() ){ winFile *pFile = (winFile*)id; if( winIsDriveLetterAndColon(pFile->zPath) && winIsOnSameVolume(pFile) ){ WCHAR zDisk[] = L"\\\\.\\_:\0"; /* underscore will be drive letter */ HANDLE hDisk; zDisk[4] = (WCHAR)pFile->zPath[0]; /* 'A' to 'Z' only, upper/lower case */ assert( (zDisk[4]>=L'A' && zDisk[4]<=L'Z') || (zDisk[4]>=L'a' && zDisk[4]<=L'z') ); hDisk = osCreateFileW(zDisk, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hDisk!=NULL ){ STORAGE_PROPERTY_QUERY query; STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignment; DWORD bytes = 0; memset(&query, 0, sizeof(STORAGE_PROPERTY_QUERY)); memset(&alignment, 0, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR)); query.QueryType = PropertyStandardQuery; query.PropertyId = StorageAccessAlignmentProperty; if( osDeviceIoControl(hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(STORAGE_PROPERTY_QUERY), &alignment, sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), &bytes, NULL) ){ DWORD size = alignment.BytesPerPhysicalSector; OSTRACE(("SECTOR file=%p, size=%lu\n", pFile->h, size)); if( size>0 && size<=2147483647 ){ return (int)size; } }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize2", pFile->zPath); } osCloseHandle(hDisk); }else{ pFile->lastErrno = osGetLastError(); winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winSectorSize3", pFile->zPath); } } } #endif (void)id; return SQLITE_DEFAULT_SECTOR_SIZE; } /* ** Return a vector of device characteristics. */ |
︙ | ︙ | |||
5919 5920 5921 5922 5923 5924 5925 | winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; #endif /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ | | | 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 | winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; #endif /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==83 ); /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); #if SQLITE_OS_WINRT osGetNativeSystemInfo(&winSysInfo); #else osGetSystemInfo(&winSysInfo); |
︙ | ︙ |