00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include "os0proc.h"
00028 #ifdef UNIV_NONINL
00029 #include "os0proc.ic"
00030 #endif
00031
00032 #include "ut0mem.h"
00033 #include "ut0byte.h"
00034 #include <errno.h>
00035 #include <unistd.h>
00036
00037
00038
00039 #if defined(MAP_ANONYMOUS)
00040 #define OS_MAP_ANON MAP_ANONYMOUS
00041 #elif defined(MAP_ANON)
00042 #define OS_MAP_ANON MAP_ANON
00043 #endif
00044
00045 UNIV_INTERN ibool os_use_large_pages;
00046
00047 UNIV_INTERN ulint os_large_page_size;
00048
00049
00055 UNIV_INTERN
00056 ulint
00057 os_proc_get_number(void)
00058
00059 {
00060 #ifdef __WIN__
00061 return((ulint)GetCurrentProcessId());
00062 #else
00063 return((ulint)getpid());
00064 #endif
00065 }
00066
00067
00070 UNIV_INTERN
00071 void*
00072 os_mem_alloc_large(
00073
00074 ulint* n)
00075 {
00076 void* ptr;
00077 ulint size;
00078 #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
00079 int shmid;
00080 struct shmid_ds buf;
00081
00082 if (!os_use_large_pages || !os_large_page_size) {
00083 goto skip;
00084 }
00085
00086
00087 ut_ad(ut_is_2pow(os_large_page_size));
00088 size = ut_2pow_round(*n + (os_large_page_size - 1),
00089 os_large_page_size);
00090
00091 shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
00092 if (shmid < 0) {
00093 fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
00094 " %lu bytes. errno %d\n", size, errno);
00095 ptr = NULL;
00096 } else {
00097 ptr = shmat(shmid, NULL, 0);
00098 if (ptr == (void *)-1) {
00099 fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
00100 " attach shared memory segment, errno %d\n",
00101 errno);
00102 ptr = NULL;
00103 }
00104
00105
00106
00107
00108 shmctl(shmid, IPC_RMID, &buf);
00109 }
00110
00111 if (ptr) {
00112 *n = size;
00113 os_fast_mutex_lock(&ut_list_mutex);
00114 ut_total_allocated_memory += size;
00115 os_fast_mutex_unlock(&ut_list_mutex);
00116 # ifdef UNIV_SET_MEM_TO_ZERO
00117 memset(ptr, '\0', size);
00118 # endif
00119 UNIV_MEM_ALLOC(ptr, size);
00120 return(ptr);
00121 }
00122
00123 fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
00124 " memory pool\n");
00125 skip:
00126 #endif
00127
00128 #ifdef __WIN__
00129 SYSTEM_INFO system_info;
00130 GetSystemInfo(&system_info);
00131
00132
00133 ut_ad(ut_is_2pow(system_info.dwPageSize));
00134
00135
00136 size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1),
00137 (ulint) system_info.dwPageSize);
00138 ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
00139 PAGE_READWRITE);
00140 if (!ptr) {
00141 fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
00142 " Windows error %lu\n",
00143 (ulong) size, (ulong) GetLastError());
00144 } else {
00145 os_fast_mutex_lock(&ut_list_mutex);
00146 ut_total_allocated_memory += size;
00147 os_fast_mutex_unlock(&ut_list_mutex);
00148 UNIV_MEM_ALLOC(ptr, size);
00149 }
00150 #elif !defined OS_MAP_ANON
00151 size = *n;
00152 ptr = ut_malloc_low(size, TRUE, FALSE);
00153 #else
00154 # ifdef HAVE_GETPAGESIZE
00155 size = getpagesize();
00156 # else
00157 size = UNIV_PAGE_SIZE;
00158 # endif
00159
00160 ut_ad(ut_is_2pow(size));
00161 size = *n = ut_2pow_round(*n + (size - 1), size);
00162 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
00163 MAP_PRIVATE | OS_MAP_ANON, -1, 0);
00164 if (UNIV_UNLIKELY(ptr == (void*) -1)) {
00165 fprintf(stderr, "InnoDB: mmap(%lu bytes) failed;"
00166 " errno %lu\n",
00167 (ulong) size, (ulong) errno);
00168 ptr = NULL;
00169 } else {
00170 os_fast_mutex_lock(&ut_list_mutex);
00171 ut_total_allocated_memory += size;
00172 os_fast_mutex_unlock(&ut_list_mutex);
00173 UNIV_MEM_ALLOC(ptr, size);
00174 }
00175 #endif
00176 return(ptr);
00177 }
00178
00179
00181 UNIV_INTERN
00182 void
00183 os_mem_free_large(
00184
00185 void *ptr,
00187 ulint size)
00189 {
00190 os_fast_mutex_lock(&ut_list_mutex);
00191 ut_a(ut_total_allocated_memory >= size);
00192 os_fast_mutex_unlock(&ut_list_mutex);
00193
00194 #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
00195 if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
00196 os_fast_mutex_lock(&ut_list_mutex);
00197 ut_a(ut_total_allocated_memory >= size);
00198 ut_total_allocated_memory -= size;
00199 os_fast_mutex_unlock(&ut_list_mutex);
00200 UNIV_MEM_FREE(ptr, size);
00201 return;
00202 }
00203 #endif
00204 #ifdef __WIN__
00205
00206
00207 if (!VirtualFree(ptr, 0, MEM_RELEASE)) {
00208 fprintf(stderr, "InnoDB: VirtualFree(%p, %lu) failed;"
00209 " Windows error %lu\n",
00210 ptr, (ulong) size, (ulong) GetLastError());
00211 } else {
00212 os_fast_mutex_lock(&ut_list_mutex);
00213 ut_a(ut_total_allocated_memory >= size);
00214 ut_total_allocated_memory -= size;
00215 os_fast_mutex_unlock(&ut_list_mutex);
00216 UNIV_MEM_FREE(ptr, size);
00217 }
00218 #elif !defined OS_MAP_ANON
00219 ut_free(ptr);
00220 #else
00221 if (munmap(static_cast<char *>(ptr), size)) {
00222 fprintf(stderr, "InnoDB: munmap(%p, %lu) failed;"
00223 " errno %lu\n",
00224 ptr, (ulong) size, (ulong) errno);
00225 } else {
00226 os_fast_mutex_lock(&ut_list_mutex);
00227 ut_a(ut_total_allocated_memory >= size);
00228 ut_total_allocated_memory -= size;
00229 os_fast_mutex_unlock(&ut_list_mutex);
00230 UNIV_MEM_FREE(ptr, size);
00231 }
00232 #endif
00233 }