Home | History | Annotate | Download | only in C
      1 /* Alloc.c -- Memory allocation functions
      2 2013-11-12 : Igor Pavlov : Public domain */
      3 
      4 #include "Precomp.h"
      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