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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
21
The interface to the operating system
22
process control primitives
24
Created 9/30/1995 Heikki Tuuri
25
*******************************************************/
37
/* FreeBSD for example has only MAP_ANON, Linux has MAP_ANONYMOUS and
38
MAP_ANON but MAP_ANON is marked as deprecated */
39
#if defined(MAP_ANONYMOUS)
40
#define OS_MAP_ANON MAP_ANONYMOUS
41
#elif defined(MAP_ANON)
42
#define OS_MAP_ANON MAP_ANON
45
UNIV_INTERN ibool os_use_large_pages;
46
/* Large page size. This may be a boot-time option on some platforms */
47
UNIV_INTERN ulint os_large_page_size;
49
/****************************************************************//**
50
Converts the current process id to a number. It is not guaranteed that the
51
number is unique. In Linux returns the 'process number' of the current
52
thread. That number is the same as one sees in 'top', for example. In Linux
53
the thread id is not the same as one sees in 'top'.
54
@return process id as a number */
57
os_proc_get_number(void)
58
/*====================*/
61
return((ulint)GetCurrentProcessId());
63
return((ulint)getpid());
67
/****************************************************************//**
68
Allocates large pages memory.
69
@return allocated memory */
74
ulint* n) /*!< in/out: number of bytes */
78
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
82
if (!os_use_large_pages || !os_large_page_size) {
86
/* Align block size to os_large_page_size */
87
ut_ad(ut_is_2pow(os_large_page_size));
88
size = ut_2pow_round(*n + (os_large_page_size - 1),
91
shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
93
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
94
" %lu bytes. errno %d\n", size, errno);
97
ptr = shmat(shmid, NULL, 0);
98
if (ptr == (void *)-1) {
99
fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
100
" attach shared memory segment, errno %d\n",
105
/* Remove the shared memory segment so that it will be
106
automatically freed after memory is detached or
108
shmctl(shmid, IPC_RMID, &buf);
113
os_fast_mutex_lock(&ut_list_mutex);
114
ut_total_allocated_memory += size;
115
os_fast_mutex_unlock(&ut_list_mutex);
116
# ifdef UNIV_SET_MEM_TO_ZERO
117
memset(ptr, '\0', size);
119
UNIV_MEM_ALLOC(ptr, size);
123
fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
126
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
129
SYSTEM_INFO system_info;
130
GetSystemInfo(&system_info);
132
/* Align block size to system page size */
133
ut_ad(ut_is_2pow(system_info.dwPageSize));
134
/* system_info.dwPageSize is only 32-bit. Casting to ulint is required
135
on 64-bit Windows. */
136
size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1),
137
(ulint) system_info.dwPageSize);
138
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
141
fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
142
" Windows error %lu\n",
143
(ulong) size, (ulong) GetLastError());
145
os_fast_mutex_lock(&ut_list_mutex);
146
ut_total_allocated_memory += size;
147
os_fast_mutex_unlock(&ut_list_mutex);
148
UNIV_MEM_ALLOC(ptr, size);
150
#elif !defined OS_MAP_ANON
152
ptr = ut_malloc_low(size, TRUE, FALSE);
154
# ifdef HAVE_GETPAGESIZE
155
size = getpagesize();
157
size = UNIV_PAGE_SIZE;
159
/* Align block size to system page size */
160
ut_ad(ut_is_2pow(size));
161
size = *n = ut_2pow_round(*n + (size - 1), size);
162
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
163
MAP_PRIVATE | OS_MAP_ANON, -1, 0);
164
if (UNIV_UNLIKELY(ptr == (void*) -1)) {
165
fprintf(stderr, "InnoDB: mmap(%lu bytes) failed;"
167
(ulong) size, (ulong) errno);
170
os_fast_mutex_lock(&ut_list_mutex);
171
ut_total_allocated_memory += size;
172
os_fast_mutex_unlock(&ut_list_mutex);
173
UNIV_MEM_ALLOC(ptr, size);
179
/****************************************************************//**
180
Frees large pages memory. */
185
void *ptr, /*!< in: pointer returned by
186
os_mem_alloc_large() */
187
ulint size) /*!< in: size returned by
188
os_mem_alloc_large() */
190
os_fast_mutex_lock(&ut_list_mutex);
191
ut_a(ut_total_allocated_memory >= size);
192
os_fast_mutex_unlock(&ut_list_mutex);
194
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
195
if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
196
os_fast_mutex_lock(&ut_list_mutex);
197
ut_a(ut_total_allocated_memory >= size);
198
ut_total_allocated_memory -= size;
199
os_fast_mutex_unlock(&ut_list_mutex);
200
UNIV_MEM_FREE(ptr, size);
203
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
205
/* When RELEASE memory, the size parameter must be 0.
206
Do not use MEM_RELEASE with MEM_DECOMMIT. */
207
if (!VirtualFree(ptr, 0, MEM_RELEASE)) {
208
fprintf(stderr, "InnoDB: VirtualFree(%p, %lu) failed;"
209
" Windows error %lu\n",
210
ptr, (ulong) size, (ulong) GetLastError());
212
os_fast_mutex_lock(&ut_list_mutex);
213
ut_a(ut_total_allocated_memory >= size);
214
ut_total_allocated_memory -= size;
215
os_fast_mutex_unlock(&ut_list_mutex);
216
UNIV_MEM_FREE(ptr, size);
218
#elif !defined OS_MAP_ANON
221
if (munmap(ptr, size)) {
222
fprintf(stderr, "InnoDB: munmap(%p, %lu) failed;"
224
ptr, (ulong) size, (ulong) errno);
226
os_fast_mutex_lock(&ut_list_mutex);
227
ut_a(ut_total_allocated_memory >= size);
228
ut_total_allocated_memory -= size;
229
os_fast_mutex_unlock(&ut_list_mutex);
230
UNIV_MEM_FREE(ptr, size);