ce188d4d |
1 | /* Alloc.c -- Memory allocation functions\r |
2 | 2015-02-21 : Igor Pavlov : Public domain */\r |
3 | \r |
4 | #include "Precomp.h"\r |
5 | \r |
6 | #ifdef _WIN32\r |
7 | #include <windows.h>\r |
8 | #endif\r |
9 | #include <stdlib.h>\r |
10 | \r |
11 | #include "Alloc.h"\r |
12 | \r |
13 | /* #define _SZ_ALLOC_DEBUG */\r |
14 | \r |
15 | /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */\r |
16 | #ifdef _SZ_ALLOC_DEBUG\r |
17 | #include <stdio.h>\r |
18 | int g_allocCount = 0;\r |
19 | int g_allocCountMid = 0;\r |
20 | int g_allocCountBig = 0;\r |
21 | #endif\r |
22 | \r |
23 | void *MyAlloc(size_t size)\r |
24 | {\r |
25 | if (size == 0)\r |
26 | return 0;\r |
27 | #ifdef _SZ_ALLOC_DEBUG\r |
28 | {\r |
29 | void *p = malloc(size);\r |
30 | fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);\r |
31 | return p;\r |
32 | }\r |
33 | #else\r |
34 | return malloc(size);\r |
35 | #endif\r |
36 | }\r |
37 | \r |
38 | void MyFree(void *address)\r |
39 | {\r |
40 | #ifdef _SZ_ALLOC_DEBUG\r |
41 | if (address != 0)\r |
42 | fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);\r |
43 | #endif\r |
44 | free(address);\r |
45 | }\r |
46 | \r |
47 | #ifdef _WIN32\r |
48 | \r |
49 | void *MidAlloc(size_t size)\r |
50 | {\r |
51 | if (size == 0)\r |
52 | return 0;\r |
53 | #ifdef _SZ_ALLOC_DEBUG\r |
54 | fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);\r |
55 | #endif\r |
56 | return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);\r |
57 | }\r |
58 | \r |
59 | void MidFree(void *address)\r |
60 | {\r |
61 | #ifdef _SZ_ALLOC_DEBUG\r |
62 | if (address != 0)\r |
63 | fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);\r |
64 | #endif\r |
65 | if (address == 0)\r |
66 | return;\r |
67 | VirtualFree(address, 0, MEM_RELEASE);\r |
68 | }\r |
69 | \r |
70 | #ifndef MEM_LARGE_PAGES\r |
71 | #undef _7ZIP_LARGE_PAGES\r |
72 | #endif\r |
73 | \r |
74 | #ifdef _7ZIP_LARGE_PAGES\r |
75 | SIZE_T g_LargePageSize = 0;\r |
76 | typedef SIZE_T (WINAPI *GetLargePageMinimumP)();\r |
77 | #endif\r |
78 | \r |
79 | void SetLargePageSize()\r |
80 | {\r |
81 | #ifdef _7ZIP_LARGE_PAGES\r |
82 | SIZE_T size = 0;\r |
83 | GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)\r |
84 | GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");\r |
85 | if (largePageMinimum == 0)\r |
86 | return;\r |
87 | size = largePageMinimum();\r |
88 | if (size == 0 || (size & (size - 1)) != 0)\r |
89 | return;\r |
90 | g_LargePageSize = size;\r |
91 | #endif\r |
92 | }\r |
93 | \r |
94 | \r |
95 | void *BigAlloc(size_t size)\r |
96 | {\r |
97 | if (size == 0)\r |
98 | return 0;\r |
99 | #ifdef _SZ_ALLOC_DEBUG\r |
100 | fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);\r |
101 | #endif\r |
102 | \r |
103 | #ifdef _7ZIP_LARGE_PAGES\r |
104 | if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))\r |
105 | {\r |
106 | void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),\r |
107 | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);\r |
108 | if (res != 0)\r |
109 | return res;\r |
110 | }\r |
111 | #endif\r |
112 | return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);\r |
113 | }\r |
114 | \r |
115 | void BigFree(void *address)\r |
116 | {\r |
117 | #ifdef _SZ_ALLOC_DEBUG\r |
118 | if (address != 0)\r |
119 | fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);\r |
120 | #endif\r |
121 | \r |
122 | if (address == 0)\r |
123 | return;\r |
124 | VirtualFree(address, 0, MEM_RELEASE);\r |
125 | }\r |
126 | \r |
127 | #endif\r |
128 | \r |
129 | \r |
130 | static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }\r |
131 | static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }\r |
132 | ISzAlloc g_Alloc = { SzAlloc, SzFree };\r |
133 | \r |
134 | static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }\r |
135 | static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }\r |
136 | ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };\r |