Squashed 'third_party/git/' content from commit cb71568594
git-subtree-dir: third_party/git git-subtree-split: cb715685942260375e1eb8153b0768a376e4ece7
This commit is contained in:
commit
1b593e1ea4
3629 changed files with 1139935 additions and 0 deletions
157
t/helper/test-drop-caches.c
Normal file
157
t/helper/test-drop-caches.c
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#include "test-tool.h"
|
||||
#include "git-compat-util.h"
|
||||
|
||||
#if defined(GIT_WINDOWS_NATIVE)
|
||||
#include "lazyload.h"
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
char Buffer[MAX_PATH];
|
||||
DWORD dwRet;
|
||||
char szVolumeAccessPath[] = "\\\\.\\X:";
|
||||
HANDLE hVolWrite;
|
||||
int success = 0;
|
||||
|
||||
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
|
||||
if ((0 == dwRet) || (dwRet > MAX_PATH))
|
||||
return error("Error getting current directory");
|
||||
|
||||
if (!has_dos_drive_prefix(Buffer))
|
||||
return error("'%s': invalid drive letter", Buffer);
|
||||
|
||||
szVolumeAccessPath[4] = Buffer[0];
|
||||
hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hVolWrite)
|
||||
return error("Unable to open volume for writing, need admin access");
|
||||
|
||||
success = FlushFileBuffers(hVolWrite);
|
||||
if (!success)
|
||||
error("Unable to flush volume");
|
||||
|
||||
CloseHandle(hVolWrite);
|
||||
|
||||
return !success;
|
||||
}
|
||||
|
||||
#define STATUS_SUCCESS (0x00000000L)
|
||||
#define STATUS_PRIVILEGE_NOT_HELD (0xC0000061L)
|
||||
|
||||
typedef enum _SYSTEM_INFORMATION_CLASS {
|
||||
SystemMemoryListInformation = 80,
|
||||
} SYSTEM_INFORMATION_CLASS;
|
||||
|
||||
typedef enum _SYSTEM_MEMORY_LIST_COMMAND {
|
||||
MemoryCaptureAccessedBits,
|
||||
MemoryCaptureAndResetAccessedBits,
|
||||
MemoryEmptyWorkingSets,
|
||||
MemoryFlushModifiedList,
|
||||
MemoryPurgeStandbyList,
|
||||
MemoryPurgeLowPriorityStandbyList,
|
||||
MemoryCommandMax
|
||||
} SYSTEM_MEMORY_LIST_COMMAND;
|
||||
|
||||
static BOOL GetPrivilege(HANDLE TokenHandle, LPCSTR lpName, int flags)
|
||||
{
|
||||
BOOL bResult;
|
||||
DWORD dwBufferLength;
|
||||
LUID luid;
|
||||
TOKEN_PRIVILEGES tpPreviousState;
|
||||
TOKEN_PRIVILEGES tpNewState;
|
||||
|
||||
dwBufferLength = 16;
|
||||
bResult = LookupPrivilegeValueA(0, lpName, &luid);
|
||||
if (bResult) {
|
||||
tpNewState.PrivilegeCount = 1;
|
||||
tpNewState.Privileges[0].Luid = luid;
|
||||
tpNewState.Privileges[0].Attributes = 0;
|
||||
bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpNewState,
|
||||
(DWORD)((LPBYTE)&(tpNewState.Privileges[1]) - (LPBYTE)&tpNewState),
|
||||
&tpPreviousState, &dwBufferLength);
|
||||
if (bResult) {
|
||||
tpPreviousState.PrivilegeCount = 1;
|
||||
tpPreviousState.Privileges[0].Luid = luid;
|
||||
tpPreviousState.Privileges[0].Attributes = flags != 0 ? 2 : 0;
|
||||
bResult = AdjustTokenPrivileges(TokenHandle, 0, &tpPreviousState,
|
||||
dwBufferLength, 0, 0);
|
||||
}
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
HANDLE hToken;
|
||||
DECLARE_PROC_ADDR(ntdll.dll, DWORD, NtSetSystemInformation, INT, PVOID, ULONG);
|
||||
SYSTEM_MEMORY_LIST_COMMAND command;
|
||||
int status;
|
||||
|
||||
if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||
return error("Can't open current process token");
|
||||
|
||||
if (!GetPrivilege(hToken, "SeProfileSingleProcessPrivilege", 1))
|
||||
return error("Can't get SeProfileSingleProcessPrivilege");
|
||||
|
||||
CloseHandle(hToken);
|
||||
|
||||
if (!INIT_PROC_ADDR(NtSetSystemInformation))
|
||||
return error("Could not find NtSetSystemInformation() function");
|
||||
|
||||
command = MemoryPurgeStandbyList;
|
||||
status = NtSetSystemInformation(
|
||||
SystemMemoryListInformation,
|
||||
&command,
|
||||
sizeof(SYSTEM_MEMORY_LIST_COMMAND)
|
||||
);
|
||||
if (status == STATUS_PRIVILEGE_NOT_HELD)
|
||||
error("Insufficient privileges to purge the standby list, need admin access");
|
||||
else if (status != STATUS_SUCCESS)
|
||||
error("Unable to execute the memory list command %d", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return system("sync");
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return system("echo 3 | sudo tee /proc/sys/vm/drop_caches");
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return system("sync");
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return system("sudo purge");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int cmd_sync(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_dropcaches(void)
|
||||
{
|
||||
return error("drop caches not implemented on this platform");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int cmd__drop_caches(int argc, const char **argv)
|
||||
{
|
||||
cmd_sync();
|
||||
return cmd_dropcaches();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue