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