git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
blob 838760898b6f4ccfc0d7a3c4bd2c8653020a93ec 4053 bytes (raw)
name: t/helper/test-drop-caches.c 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
 
#include "test-tool.h"
#include "git-compat-util.h"

#if defined(GIT_WINDOWS_NATIVE)

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 ((Buffer[0] < 'A') || (Buffer[0] > 'Z'))
		return error("Invalid drive letter '%c'", Buffer[0]);

	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;
	HMODULE ntdll;
	DWORD(WINAPI *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);

	ntdll = LoadLibrary("ntdll.dll");
	if (!ntdll)
		return error("Can't load ntdll.dll, wrong Windows version?");

	NtSetSystemInformation =
		(DWORD(WINAPI *)(INT, PVOID, ULONG))GetProcAddress(ntdll, "NtSetSystemInformation");
	if (!NtSetSystemInformation)
		return error("Can't get function addresses, wrong Windows version?");

	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);

	FreeLibrary(ntdll);

	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();
}

debug log:

solving 838760898b ...
found 838760898b in https://80x24.org/mirrors/git.git

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).