Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pfapp.c
  5. Abstract:
  6. This module builds a console test program that can be launched
  7. to test/stress the application launch prefetcher.
  8. The quality of the code for the test programs is as such.
  9. Author:
  10. Cenk Ergan (cenke)
  11. Environment:
  12. User Mode
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <time.h>
  21. DWORD
  22. PfAppGetViewOfFile(
  23. IN WCHAR *FilePath,
  24. OUT PVOID *BasePointer,
  25. OUT PULONG FileSize
  26. )
  27. /*++
  28. Routine Description:
  29. Map the all of the specified file to memory.
  30. Arguments:
  31. FilePath - NUL terminated path to file to map.
  32. BasePointer - Start address of mapping will be returned here.
  33. FileSize - Size of the mapping/file will be returned here.
  34. Return Value:
  35. Win32 error code.
  36. --*/
  37. {
  38. HANDLE InputHandle;
  39. HANDLE InputMappingHandle;
  40. DWORD ErrorCode;
  41. DWORD SizeL;
  42. DWORD SizeH;
  43. BOOLEAN OpenedFile;
  44. BOOLEAN CreatedFileMapping;
  45. //
  46. // Initialize locals.
  47. //
  48. OpenedFile = FALSE;
  49. CreatedFileMapping = FALSE;
  50. //
  51. // Note that we are opening the file exclusively. This guarantees
  52. // that for trace files as long as the kernel is not done writing
  53. // it we can't open the file, which guarantees we won't have an
  54. // incomplete file to worry about.
  55. //
  56. InputHandle = CreateFile(FilePath,
  57. GENERIC_READ,
  58. 0,
  59. NULL,
  60. OPEN_EXISTING,
  61. FILE_SHARE_READ,
  62. NULL);
  63. if (INVALID_HANDLE_VALUE == InputHandle)
  64. {
  65. ErrorCode = GetLastError();
  66. goto cleanup;
  67. }
  68. OpenedFile = TRUE;
  69. SizeL = GetFileSize(InputHandle, &SizeH);
  70. if (SizeL == -1 && (GetLastError() != NO_ERROR )) {
  71. ErrorCode = GetLastError();
  72. goto cleanup;
  73. }
  74. if (SizeH) {
  75. ErrorCode = ERROR_BAD_LENGTH;
  76. goto cleanup;
  77. }
  78. if (FileSize) {
  79. *FileSize = SizeL;
  80. }
  81. InputMappingHandle = CreateFileMapping(InputHandle,
  82. 0,
  83. PAGE_READONLY,
  84. 0,
  85. 0,
  86. NULL);
  87. if (NULL == InputMappingHandle)
  88. {
  89. ErrorCode = GetLastError();
  90. goto cleanup;
  91. }
  92. CreatedFileMapping = TRUE;
  93. *BasePointer = MapViewOfFile(InputMappingHandle,
  94. FILE_MAP_READ,
  95. 0,
  96. 0,
  97. 0);
  98. if (NULL == *BasePointer) {
  99. ErrorCode = GetLastError();
  100. goto cleanup;
  101. }
  102. ErrorCode = ERROR_SUCCESS;
  103. cleanup:
  104. if (OpenedFile) {
  105. CloseHandle(InputHandle);
  106. }
  107. if (CreatedFileMapping) {
  108. CloseHandle(InputMappingHandle);
  109. }
  110. return ErrorCode;
  111. }
  112. PWCHAR
  113. PfAppAnsiToUnicode(
  114. PCHAR str
  115. )
  116. /*++
  117. Routine Description:
  118. This routine converts an ANSI string into an allocated wide
  119. character string. The returned string should be freed by
  120. free().
  121. Arguments:
  122. str - Pointer to string to convert.
  123. Return Value:
  124. Allocated wide character string or NULL if there is a failure.
  125. --*/
  126. {
  127. ULONG len;
  128. wchar_t *retstr = NULL;
  129. len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  130. retstr = (wchar_t *)malloc(len * sizeof(wchar_t));
  131. if (!retstr)
  132. {
  133. return NULL;
  134. }
  135. MultiByteToWideChar(CP_ACP, 0, str, -1, retstr, len);
  136. return retstr;
  137. }
  138. //
  139. // This does not have to be the actual page size on the platform. It is the
  140. // granularity with which we will make accesses.
  141. //
  142. #define MY_PAGE_SIZE 4096
  143. #define PFAPP_MAX_DATA_PAGES 256
  144. char Data[PFAPP_MAX_DATA_PAGES * MY_PAGE_SIZE] = {1};
  145. #define PFAPP_MAX_FUNCS 16
  146. #pragma code_seg("func0")
  147. DWORD func0(VOID) {return ERROR_SUCCESS;};
  148. #pragma code_seg("func1")
  149. DWORD func1(VOID) {return ERROR_SUCCESS;};
  150. #pragma code_seg("func2")
  151. DWORD func2(VOID) {return ERROR_SUCCESS;};
  152. #pragma code_seg("func3")
  153. DWORD func3(VOID) {return ERROR_SUCCESS;};
  154. #pragma code_seg("func4")
  155. DWORD func4(VOID) {return ERROR_SUCCESS;};
  156. #pragma code_seg("func5")
  157. DWORD func5(VOID) {return ERROR_SUCCESS;};
  158. #pragma code_seg("func6")
  159. DWORD func6(VOID) {return ERROR_SUCCESS;};
  160. #pragma code_seg("func7")
  161. DWORD func7(VOID) {return ERROR_SUCCESS;};
  162. #pragma code_seg("func8")
  163. DWORD func8(VOID) {return ERROR_SUCCESS;};
  164. #pragma code_seg("func9")
  165. DWORD func9(VOID) {return ERROR_SUCCESS;};
  166. #pragma code_seg("func10")
  167. DWORD func10(VOID) {return ERROR_SUCCESS;};
  168. #pragma code_seg("func11")
  169. DWORD func11(VOID) {return ERROR_SUCCESS;};
  170. #pragma code_seg("func12")
  171. DWORD func12(VOID) {return ERROR_SUCCESS;};
  172. #pragma code_seg("func13")
  173. DWORD func13(VOID) {return ERROR_SUCCESS;};
  174. #pragma code_seg("func14")
  175. DWORD func14(VOID) {return ERROR_SUCCESS;};
  176. #pragma code_seg("func15")
  177. DWORD func15(VOID) {return ERROR_SUCCESS;};
  178. #pragma code_seg()
  179. char *PfAppUsage = "pfapp.exe -data datafile\n";
  180. INT
  181. __cdecl
  182. main(
  183. INT argc,
  184. PCHAR argv[]
  185. )
  186. {
  187. WCHAR *CommandLine;
  188. WCHAR *Argument;
  189. WCHAR *DataFile;
  190. PCHAR BasePointer;
  191. DWORD FileSize;
  192. DWORD FileSizeInMyPages;
  193. DWORD ErrorCode;
  194. DWORD FuncNo;
  195. DWORD NumCalls;
  196. DWORD CallIdx;
  197. DWORD DataPage;
  198. DWORD NumDataAccesses;
  199. DWORD DataAccessIdx;
  200. DWORD Sum;
  201. //
  202. // Initialize locals.
  203. //
  204. CommandLine = GetCommandLine();
  205. DataFile = NULL;
  206. BasePointer = NULL;
  207. //
  208. // Initialize random generator.
  209. //
  210. srand((unsigned)time(NULL));
  211. //
  212. // Check arguments.
  213. //
  214. if (argc != 3) {
  215. printf(PfAppUsage);
  216. ErrorCode = ERROR_INVALID_PARAMETER;
  217. goto cleanup;
  218. }
  219. //
  220. // Call functions. Each one is on a different page. Basing the number of calls
  221. // we will make on number of functions/pages we have leads to more interesting
  222. // access patterns and prefetch policy decisions.
  223. //
  224. NumCalls = rand() % PFAPP_MAX_FUNCS;
  225. NumCalls += PFAPP_MAX_FUNCS / 4;
  226. for (CallIdx = 0; CallIdx < NumCalls; CallIdx++) {
  227. FuncNo = rand() % PFAPP_MAX_FUNCS;
  228. switch(FuncNo) {
  229. case 0: func0(); break;
  230. case 1: func1(); break;
  231. case 2: func2(); break;
  232. case 3: func3(); break;
  233. case 4: func4(); break;
  234. case 5: func5(); break;
  235. case 6: func6(); break;
  236. case 7: func7(); break;
  237. case 8: func8(); break;
  238. case 9: func9(); break;
  239. case 10: func10(); break;
  240. case 11: func11(); break;
  241. case 12: func12(); break;
  242. case 13: func13(); break;
  243. case 14: func14(); break;
  244. case 15: func15(); break;
  245. default: break;
  246. }
  247. }
  248. //
  249. // Access pages in the data section. Basing the number of accesses
  250. // we will make on number of pages we have adds more regularity to our
  251. // accesses so they survive sensitivity based prefetch policy decisions.
  252. //
  253. NumDataAccesses = rand() % PFAPP_MAX_DATA_PAGES;
  254. NumDataAccesses += PFAPP_MAX_DATA_PAGES / 4;
  255. Sum = 0;
  256. for (DataAccessIdx = 0; DataAccessIdx < NumDataAccesses; DataAccessIdx++) {
  257. DataPage = rand() % PFAPP_MAX_DATA_PAGES;
  258. Sum += Data[DataPage * MY_PAGE_SIZE];
  259. }
  260. printf("Bogus sum1 is %d\n", Sum);
  261. //
  262. // Map the executable as data.
  263. //
  264. DataFile = PfAppAnsiToUnicode(argv[2]);
  265. if (!DataFile) {
  266. ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
  267. goto cleanup;
  268. }
  269. ErrorCode = PfAppGetViewOfFile(DataFile, &BasePointer, &FileSize);
  270. if (ErrorCode != ERROR_SUCCESS) {
  271. printf("Could not map data file: %x\n", ErrorCode);
  272. goto cleanup;
  273. }
  274. FileSizeInMyPages = FileSize / MY_PAGE_SIZE;
  275. //
  276. // Touch the pages of the executable as data pages.
  277. //
  278. NumDataAccesses = rand() % FileSizeInMyPages;
  279. NumDataAccesses += FileSizeInMyPages / 4;
  280. Sum = 0;
  281. for (DataAccessIdx = 0; DataAccessIdx < NumDataAccesses; DataAccessIdx++) {
  282. DataPage = rand() % FileSizeInMyPages;
  283. Sum += BasePointer[DataPage * MY_PAGE_SIZE];
  284. }
  285. printf("Bogus sum2 is %d\n", Sum);
  286. ErrorCode = ERROR_SUCCESS;
  287. cleanup:
  288. if (DataFile) {
  289. free(DataFile);
  290. }
  291. if (BasePointer) {
  292. UnmapViewOfFile(BasePointer);
  293. }
  294. return ErrorCode;
  295. }