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