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