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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/**************************************************//**
21
The interface to the operating system
22
process control primitives
24
Created 9/30/1995 Heikki Tuuri
25
*******************************************************/
36
/* FreeBSD for example has only MAP_ANON, Linux has MAP_ANONYMOUS and
37
MAP_ANON but MAP_ANON is marked as deprecated */
38
#if defined(MAP_ANONYMOUS)
39
#define OS_MAP_ANON MAP_ANONYMOUS
40
#elif defined(MAP_ANON)
41
#define OS_MAP_ANON MAP_ANON
44
UNIV_INTERN ibool os_use_large_pages;
45
/* Large page size. This may be a boot-time option on some platforms */
46
UNIV_INTERN ulint os_large_page_size;
48
/****************************************************************//**
49
Converts the current process id to a number. It is not guaranteed that the
50
number is unique. In Linux returns the 'process number' of the current
51
thread. That number is the same as one sees in 'top', for example. In Linux
52
the thread id is not the same as one sees in 'top'.
53
@return process id as a number */
56
os_proc_get_number(void)
57
/*====================*/
60
return((ulint)GetCurrentProcessId());
62
return((ulint)getpid());
66
/****************************************************************//**
67
Allocates large pages memory.
68
@return allocated memory */
73
ulint* n) /*!< in/out: number of bytes */
77
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
81
if (!os_use_large_pages || !os_large_page_size) {
85
/* Align block size to os_large_page_size */
86
ut_ad(ut_is_2pow(os_large_page_size));
87
size = ut_2pow_round(*n + (os_large_page_size - 1),
90
shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
92
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
93
" %lu bytes. errno %d\n", size, errno);
96
ptr = shmat(shmid, NULL, 0);
97
if (ptr == (void *)-1) {
98
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
99
" attach shared memory segment, errno %d\n",
103
/* Remove the shared memory segment so that it will be
104
automatically freed after memory is detached or
106
shmctl(shmid, IPC_RMID, &buf);
111
os_fast_mutex_lock(&ut_list_mutex);
112
ut_total_allocated_memory += size;
113
os_fast_mutex_unlock(&ut_list_mutex);
114
# ifdef UNIV_SET_MEM_TO_ZERO
115
memset(ptr, '\0', size);
117
UNIV_MEM_ALLOC(ptr, size);
121
fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
124
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
127
SYSTEM_INFO system_info;
128
GetSystemInfo(&system_info);
130
/* Align block size to system page size */
131
ut_ad(ut_is_2pow(system_info.dwPageSize));
132
/* system_info.dwPageSize is only 32-bit. Casting to ulint is required
133
on 64-bit Windows. */
134
size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1),
135
(ulint) system_info.dwPageSize);
136
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
139
fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
140
" Windows error %lu\n",
141
(ulong) size, (ulong) GetLastError());
143
os_fast_mutex_lock(&ut_list_mutex);
144
ut_total_allocated_memory += size;
145
os_fast_mutex_unlock(&ut_list_mutex);
146
UNIV_MEM_ALLOC(ptr, size);
148
#elif defined __NETWARE__ || !defined OS_MAP_ANON
150
ptr = ut_malloc_low(size, TRUE, FALSE);
152
# ifdef HAVE_GETPAGESIZE
153
size = getpagesize();
155
size = UNIV_PAGE_SIZE;
157
/* Align block size to system page size */
158
ut_ad(ut_is_2pow(size));
159
size = *n = ut_2pow_round(*n + (size - 1), size);
160
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
161
MAP_PRIVATE | OS_MAP_ANON, -1, 0);
162
if (UNIV_UNLIKELY(ptr == (void*) -1)) {
163
fprintf(stderr, "InnoDB: mmap(%lu bytes) failed;"
165
(ulong) size, (ulong) errno);
168
os_fast_mutex_lock(&ut_list_mutex);
169
ut_total_allocated_memory += size;
170
os_fast_mutex_unlock(&ut_list_mutex);
171
UNIV_MEM_ALLOC(ptr, size);
177
/****************************************************************//**
178
Frees large pages memory. */
183
void *ptr, /*!< in: pointer returned by
184
os_mem_alloc_large() */
185
ulint size) /*!< in: size returned by
186
os_mem_alloc_large() */
188
os_fast_mutex_lock(&ut_list_mutex);
189
ut_a(ut_total_allocated_memory >= size);
190
os_fast_mutex_unlock(&ut_list_mutex);
192
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
193
if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
194
os_fast_mutex_lock(&ut_list_mutex);
195
ut_a(ut_total_allocated_memory >= size);
196
ut_total_allocated_memory -= size;
197
os_fast_mutex_unlock(&ut_list_mutex);
198
UNIV_MEM_FREE(ptr, size);
201
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
203
/* When RELEASE memory, the size parameter must be 0.
204
Do not use MEM_RELEASE with MEM_DECOMMIT. */
205
if (!VirtualFree(ptr, 0, MEM_RELEASE)) {
206
fprintf(stderr, "InnoDB: VirtualFree(%p, %lu) failed;"
207
" Windows error %lu\n",
208
ptr, (ulong) size, (ulong) GetLastError());
210
os_fast_mutex_lock(&ut_list_mutex);
211
ut_a(ut_total_allocated_memory >= size);
212
ut_total_allocated_memory -= size;
213
os_fast_mutex_unlock(&ut_list_mutex);
214
UNIV_MEM_FREE(ptr, size);
216
#elif defined __NETWARE__ || !defined OS_MAP_ANON
219
if (munmap(ptr, size)) {
220
fprintf(stderr, "InnoDB: munmap(%p, %lu) failed;"
222
ptr, (ulong) size, (ulong) errno);
224
os_fast_mutex_lock(&ut_list_mutex);
225
ut_a(ut_total_allocated_memory >= size);
226
ut_total_allocated_memory -= size;
227
os_fast_mutex_unlock(&ut_list_mutex);
228
UNIV_MEM_FREE(ptr, size);