📄 os0proc.c
字号:
/******************************************************The interface to the operating systemprocess control primitives(c) 1995 Innobase OyCreated 9/30/1995 Heikki Tuuri*******************************************************/#include "os0proc.h"#ifdef UNIV_NONINL#include "os0proc.ic"#endif#include "ut0mem.h"#include "ut0byte.h"/*How to get AWE to compile on Windows?-------------------------------------In the project settings of the innobase project the Visual C++ source,__WIN2000__ has to be defined.The Visual C++ has to be relatively recent and _WIN32_WINNT has to bedefined to a value >= 0x0500 when windows.h is included.#define _WIN32_WINNT 0x0500Where does AWE work?-------------------See the error message in os_awe_allocate_physical_mem().How to assign privileges for mysqld to use AWE?-----------------------------------------------See the error message in os_awe_enable_lock_pages_in_mem().Use Windows AWE functions in this order---------------------------------------(1) os_awe_enable_lock_pages_in_mem();(2) os_awe_allocate_physical_mem();(3) os_awe_allocate_virtual_mem_window();(4) os_awe_map_physical_mem_to_window().To test 'AWE' in a computer which does not have the AWE API,you can compile with UNIV_SIMULATE_AWE defined in this file.*/#ifdef UNIV_SIMULATE_AWE/* If we simulate AWE, we allocate the 'physical memory' here */byte* os_awe_simulate_mem;ulint os_awe_simulate_mem_size;os_awe_t* os_awe_simulate_page_info;byte* os_awe_simulate_window;ulint os_awe_simulate_window_size;/* In simulated AWE the following contains a NULL pointer or a pointerto a mapped 'physical page' for each 4 kB page in the AWE window */byte** os_awe_simulate_map;#endif#ifdef __WIN2000__os_awe_t* os_awe_page_info;ulint os_awe_n_pages;byte* os_awe_window;ulint os_awe_window_size;#endifibool os_use_large_pages;/* Large page size. This may be a boot-time option on some platforms */ulint os_large_page_size;/********************************************************************Windows AWE support. Tries to enable the "lock pages in memory" privilege forthe current process so that the current process can allocate memory-lockedvirtual address space to act as the window where AWE maps physical memory. */iboolos_awe_enable_lock_pages_in_mem(void)/*=================================*/ /* out: TRUE if success, FALSE if error; prints error info to stderr if no success */{#ifdef UNIV_SIMULATE_AWE return(TRUE);#elif defined(__WIN2000__) struct { DWORD Count; LUID_AND_ATTRIBUTES Privilege[1]; } Info; HANDLE hProcess; HANDLE Token; BOOL Result; hProcess = GetCurrentProcess(); /* Open the token of the current process */ Result = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &Token); if (Result != TRUE) { fprintf(stderr, "InnoDB: AWE: Cannot open process token, error %lu\n", (ulint)GetLastError()); return(FALSE); } Info.Count = 1; Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; /* Get the local unique identifier (LUID) of the SE_LOCK_MEMORY privilege */ Result = LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &(Info.Privilege[0].Luid)); if (Result != TRUE) { fprintf(stderr, "InnoDB: AWE: Cannot get local privilege value for %s, error %lu.\n", SE_LOCK_MEMORY_NAME, (ulint)GetLastError()); return(FALSE); } /* Try to adjust the privilege */ Result = AdjustTokenPrivileges(Token, FALSE, (PTOKEN_PRIVILEGES)&Info, 0, NULL, NULL); /* Check the result */ if (Result != TRUE) { fprintf(stderr, "InnoDB: AWE: Cannot adjust process token privileges, error %u.\n", GetLastError()); return(FALSE); } else if (GetLastError() != ERROR_SUCCESS) { fprintf(stderr,"InnoDB: AWE: Cannot enable SE_LOCK_MEMORY privilege, error %lu.\n""InnoDB: In Windows XP Home you cannot use AWE. In Windows 2000 and XP\n""InnoDB: Professional you must go to the Control Panel, to\n""InnoDB: Security Settings, to Local Policies, and enable\n""InnoDB: the 'lock pages in memory' privilege for the user who runs\n""InnoDB: the MySQL server.\n", GetLastError()); return(FALSE); } CloseHandle(Token); return(TRUE);#else#ifdef __WIN__ fprintf(stderr,"InnoDB: AWE: Error: to use AWE you must use a ...-nt MySQL executable.\n");#endif return(FALSE);#endif}/********************************************************************Allocates physical RAM memory up to 64 GB in an Intel 32-bit x86processor. */iboolos_awe_allocate_physical_mem(/*=========================*/ /* out: TRUE if success */ os_awe_t** page_info, /* out, own: array of opaque data containing the info for allocated physical memory pages; each allocated 4 kB physical memory page has one slot of type os_awe_t in the array */ ulint n_megabytes) /* in: number of megabytes to allocate */{#ifdef UNIV_SIMULATE_AWE os_awe_simulate_page_info = ut_malloc(sizeof(os_awe_t) * n_megabytes * ((1024 * 1024) / OS_AWE_X86_PAGE_SIZE)); os_awe_simulate_mem = ut_align(ut_malloc( 4096 + 1024 * 1024 * n_megabytes), 4096); os_awe_simulate_mem_size = n_megabytes * 1024 * 1024; *page_info = os_awe_simulate_page_info; return(TRUE);#elif defined(__WIN2000__) BOOL bResult; os_awe_t NumberOfPages; /* Question: why does Windows use the name ULONG_PTR for a scalar integer type? Maybe because we may also refer to &NumberOfPages? */ os_awe_t NumberOfPagesInitial; SYSTEM_INFO sSysInfo; int PFNArraySize; if (n_megabytes > 64 * 1024) { fprintf(stderr,"InnoDB: AWE: Error: tried to allocate %lu MB.\n""InnoDB: AWE cannot allocate more than 64 GB in any computer.\n", n_megabytes); return(FALSE); } GetSystemInfo(&sSysInfo); /* fill the system information structure */ if ((ulint)OS_AWE_X86_PAGE_SIZE != (ulint)sSysInfo.dwPageSize) { fprintf(stderr,"InnoDB: AWE: Error: this computer has a page size of %lu.\n""InnoDB: Should be 4096 bytes for InnoDB AWE support to work.\n", (ulint)sSysInfo.dwPageSize); return(FALSE); } /* Calculate the number of pages of memory to request */ NumberOfPages = n_megabytes * ((1024 * 1024) / OS_AWE_X86_PAGE_SIZE); /* Calculate the size of page_info for allocated physical pages */ PFNArraySize = NumberOfPages * sizeof(os_awe_t); *page_info = (os_awe_t*)HeapAlloc(GetProcessHeap(), 0, PFNArraySize); if (*page_info == NULL) { fprintf(stderr,"InnoDB: AWE: Failed to allocate page info array from process heap, error %lu\n", (ulint)GetLastError()); return(FALSE); } ut_total_allocated_memory += PFNArraySize; /* Enable this process' privilege to lock pages to physical memory */ if (!os_awe_enable_lock_pages_in_mem()) { return(FALSE); } /* Allocate the physical memory */ NumberOfPagesInitial = NumberOfPages; os_awe_page_info = *page_info; os_awe_n_pages = (ulint)NumberOfPages; /* Compilation note: if the compiler complains the function is not defined, see the note at the start of this file */ bResult = AllocateUserPhysicalPages(GetCurrentProcess(), &NumberOfPages, *page_info); if (bResult != TRUE) { fprintf(stderr,"InnoDB: AWE: Cannot allocate physical pages, error %lu.\n", (ulint)GetLastError()); return(FALSE); } if (NumberOfPagesInitial != NumberOfPages) { fprintf(stderr,"InnoDB: AWE: Error: allocated only %lu pages of %lu requested.\n""InnoDB: Check that you have enough free RAM.\n""InnoDB: In Windows XP Professional and 2000 Professional\n""InnoDB: Windows PAE size is max 4 GB. In 2000 and .NET\n""InnoDB: Advanced Servers and 2000 Datacenter Server it is 32 GB,\n""InnoDB: and in .NET Datacenter Server it is 64 GB.\n""InnoDB: A Microsoft web page said that the processor must be an Intel\n""InnoDB: processor.\n", (ulint)NumberOfPages, (ulint)NumberOfPagesInitial); return(FALSE); } fprintf(stderr,"InnoDB: Using Address Windowing Extensions (AWE); allocated %lu MB\n", n_megabytes); return(TRUE); #else UT_NOT_USED(n_megabytes); UT_NOT_USED(page_info); return(FALSE);#endif}/********************************************************************Allocates a window in the virtual address space where we can map thenpages of physical memory. */byte*os_awe_allocate_virtual_mem_window(/*===============================*/ /* out, own: allocated memory, or NULL if did not succeed */ ulint size) /* in: virtual memory allocation size in bytes, must be < 2 GB */{#ifdef UNIV_SIMULATE_AWE ulint i; os_awe_simulate_window = ut_align(ut_malloc(4096 + size), 4096); os_awe_simulate_window_size = size; os_awe_simulate_map = ut_malloc(sizeof(byte*) * (size / 4096)); for (i = 0; i < (size / 4096); i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -