mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innodb_plugin / os / os0proc.c
blobf7e1cbe6859b2b9a48db77fe2e9f6089c025b7c4
1 /*****************************************************************************
3 Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *****************************************************************************/
19 /**************************************************//**
20 @file os/os0proc.c
21 The interface to the operating system
22 process control primitives
24 Created 9/30/1995 Heikki Tuuri
25 *******************************************************/
27 #include "os0proc.h"
28 #ifdef UNIV_NONINL
29 #include "os0proc.ic"
30 #endif
32 #include "ut0mem.h"
33 #include "ut0byte.h"
35 /* FreeBSD for example has only MAP_ANON, Linux has MAP_ANONYMOUS and
36 MAP_ANON but MAP_ANON is marked as deprecated */
37 #if defined(MAP_ANONYMOUS)
38 #define OS_MAP_ANON MAP_ANONYMOUS
39 #elif defined(MAP_ANON)
40 #define OS_MAP_ANON MAP_ANON
41 #endif
43 UNIV_INTERN ibool os_use_large_pages;
44 /* Large page size. This may be a boot-time option on some platforms */
45 UNIV_INTERN ulint os_large_page_size;
47 /****************************************************************//**
48 Converts the current process id to a number. It is not guaranteed that the
49 number is unique. In Linux returns the 'process number' of the current
50 thread. That number is the same as one sees in 'top', for example. In Linux
51 the thread id is not the same as one sees in 'top'.
52 @return process id as a number */
53 UNIV_INTERN
54 ulint
55 os_proc_get_number(void)
56 /*====================*/
58 #ifdef __WIN__
59 return((ulint)GetCurrentProcessId());
60 #else
61 return((ulint)getpid());
62 #endif
65 /****************************************************************//**
66 Allocates large pages memory.
67 @return allocated memory */
68 UNIV_INTERN
69 void*
70 os_mem_alloc_large(
71 /*===============*/
72 ulint* n) /*!< in/out: number of bytes */
74 void* ptr;
75 ulint size;
76 #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
77 int shmid;
78 struct shmid_ds buf;
80 if (!os_use_large_pages || !os_large_page_size) {
81 goto skip;
84 /* Align block size to os_large_page_size */
85 ut_ad(ut_is_2pow(os_large_page_size));
86 size = ut_2pow_round(*n + (os_large_page_size - 1),
87 os_large_page_size);
89 shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
90 if (shmid < 0) {
91 fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
92 " %lu bytes. errno %d\n", size, errno);
93 ptr = NULL;
94 } else {
95 ptr = shmat(shmid, NULL, 0);
96 if (ptr == (void *)-1) {
97 fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
98 " attach shared memory segment, errno %d\n",
99 errno);
100 ptr = NULL;
103 /* Remove the shared memory segment so that it will be
104 automatically freed after memory is detached or
105 process exits */
106 shmctl(shmid, IPC_RMID, &buf);
109 if (ptr) {
110 *n = size;
111 os_fast_mutex_lock(&ut_list_mutex);
112 ut_total_allocated_memory += size;
113 os_fast_mutex_unlock(&ut_list_mutex);
114 UNIV_MEM_ALLOC(ptr, size);
115 return(ptr);
118 fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
119 " memory pool\n");
120 skip:
121 #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
123 #ifdef __WIN__
124 SYSTEM_INFO system_info;
125 GetSystemInfo(&system_info);
127 /* Align block size to system page size */
128 ut_ad(ut_is_2pow(system_info.dwPageSize));
129 /* system_info.dwPageSize is only 32-bit. Casting to ulint is required
130 on 64-bit Windows. */
131 size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1),
132 (ulint) system_info.dwPageSize);
133 ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
134 PAGE_READWRITE);
135 if (!ptr) {
136 fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
137 " Windows error %lu\n",
138 (ulong) size, (ulong) GetLastError());
139 } else {
140 os_fast_mutex_lock(&ut_list_mutex);
141 ut_total_allocated_memory += size;
142 os_fast_mutex_unlock(&ut_list_mutex);
143 UNIV_MEM_ALLOC(ptr, size);
145 #elif defined __NETWARE__ || !defined OS_MAP_ANON
146 size = *n;
147 ptr = ut_malloc_low(size, TRUE, FALSE);
148 #else
149 # ifdef HAVE_GETPAGESIZE
150 size = getpagesize();
151 # else
152 size = UNIV_PAGE_SIZE;
153 # endif
154 /* Align block size to system page size */
155 ut_ad(ut_is_2pow(size));
156 size = *n = ut_2pow_round(*n + (size - 1), size);
157 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
158 MAP_PRIVATE | OS_MAP_ANON, -1, 0);
159 if (UNIV_UNLIKELY(ptr == (void*) -1)) {
160 fprintf(stderr, "InnoDB: mmap(%lu bytes) failed;"
161 " errno %lu\n",
162 (ulong) size, (ulong) errno);
163 ptr = NULL;
164 } else {
165 os_fast_mutex_lock(&ut_list_mutex);
166 ut_total_allocated_memory += size;
167 os_fast_mutex_unlock(&ut_list_mutex);
168 UNIV_MEM_ALLOC(ptr, size);
170 #endif
171 return(ptr);
174 /****************************************************************//**
175 Frees large pages memory. */
176 UNIV_INTERN
177 void
178 os_mem_free_large(
179 /*==============*/
180 void *ptr, /*!< in: pointer returned by
181 os_mem_alloc_large() */
182 ulint size) /*!< in: size returned by
183 os_mem_alloc_large() */
185 os_fast_mutex_lock(&ut_list_mutex);
186 ut_a(ut_total_allocated_memory >= size);
187 os_fast_mutex_unlock(&ut_list_mutex);
189 #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
190 if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
191 os_fast_mutex_lock(&ut_list_mutex);
192 ut_a(ut_total_allocated_memory >= size);
193 ut_total_allocated_memory -= size;
194 os_fast_mutex_unlock(&ut_list_mutex);
195 UNIV_MEM_FREE(ptr, size);
196 return;
198 #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
199 #ifdef __WIN__
200 /* When RELEASE memory, the size parameter must be 0.
201 Do not use MEM_RELEASE with MEM_DECOMMIT. */
202 if (!VirtualFree(ptr, 0, MEM_RELEASE)) {
203 fprintf(stderr, "InnoDB: VirtualFree(%p, %lu) failed;"
204 " Windows error %lu\n",
205 ptr, (ulong) size, (ulong) GetLastError());
206 } else {
207 os_fast_mutex_lock(&ut_list_mutex);
208 ut_a(ut_total_allocated_memory >= size);
209 ut_total_allocated_memory -= size;
210 os_fast_mutex_unlock(&ut_list_mutex);
211 UNIV_MEM_FREE(ptr, size);
213 #elif defined __NETWARE__ || !defined OS_MAP_ANON
214 ut_free(ptr);
215 #else
216 if (munmap(ptr, size)) {
217 fprintf(stderr, "InnoDB: munmap(%p, %lu) failed;"
218 " errno %lu\n",
219 ptr, (ulong) size, (ulong) errno);
220 } else {
221 os_fast_mutex_lock(&ut_list_mutex);
222 ut_a(ut_total_allocated_memory >= size);
223 ut_total_allocated_memory -= size;
224 os_fast_mutex_unlock(&ut_list_mutex);
225 UNIV_MEM_FREE(ptr, size);
227 #endif