4040#include "pycore_jit.h" // _PyJIT_Fini()
4141#endif
4242
43+ #if defined(PYMALLOC_USE_HUGEPAGES ) && defined(MS_WINDOWS )
44+ #include <Windows.h>
45+ #endif
46+
4347#include "opcode.h"
4448
4549#include <locale.h> // setlocale()
@@ -485,6 +489,39 @@ pyinit_core_reconfigure(_PyRuntimeState *runtime,
485489 return _PyStatus_OK ();
486490}
487491
492+ #if defined(PYMALLOC_USE_HUGEPAGES ) && defined(MS_WINDOWS )
493+ static PyStatus
494+ get_huge_pages_privilege (void )
495+ {
496+ HANDLE hToken ;
497+ if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , & hToken ))
498+ {
499+ return _PyStatus_ERR ("failed to open process token" );
500+ }
501+ TOKEN_PRIVILEGES tp ;
502+ if (!LookupPrivilegeValue (NULL , SE_LOCK_MEMORY_NAME , & tp .Privileges [0 ].Luid ))
503+ {
504+ CloseHandle (hToken );
505+ return _PyStatus_ERR ("failed to lookup SeLockMemoryPrivilege for huge pages" );
506+ }
507+ tp .PrivilegeCount = 1 ;
508+ tp .Privileges [0 ].Attributes = SE_PRIVILEGE_ENABLED ;
509+ // AdjustTokenPrivileges can return with nonzero status (i.e. success)
510+ // but without having all privileges adjusted (ERROR_NOT_ALL_ASSIGNED).
511+ BOOL status = AdjustTokenPrivileges (hToken , FALSE, & tp , sizeof (TOKEN_PRIVILEGES ), NULL , NULL );
512+ DWORD error = GetLastError ();
513+ if (!status || (error != ERROR_SUCCESS ))
514+ {
515+ CloseHandle (hToken );
516+ return _PyStatus_ERR ("failed to obtain SeLockMemoryPrivilege for huge pages" );
517+ }
518+ if (!CloseHandle (hToken ))
519+ {
520+ return _PyStatus_ERR ("failed to close process token handle" );
521+ }
522+ return _PyStatus_OK ();
523+ }
524+ #endif
488525
489526static PyStatus
490527pycore_init_runtime (_PyRuntimeState * runtime ,
@@ -499,6 +536,15 @@ pycore_init_runtime(_PyRuntimeState *runtime,
499536 return status ;
500537 }
501538
539+ #if defined(PYMALLOC_USE_HUGEPAGES ) && defined(MS_WINDOWS )
540+ if (runtime -> allocators .use_hugepages ) {
541+ status = get_huge_pages_privilege ();
542+ if (_PyStatus_EXCEPTION (status )) {
543+ return status ;
544+ }
545+ }
546+ #endif
547+
502548 /* Py_Finalize leaves _Py_Finalizing set in order to help daemon
503549 * threads behave a little more gracefully at interpreter shutdown.
504550 * We clobber it here so the new interpreter can start with a clean
0 commit comments