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