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 /**************************************************//**
21 The interface to the operating system
22 process control primitives
24 Created 9/30/1995 Heikki Tuuri
25 *******************************************************/
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
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 */
55 os_proc_get_number(void)
56 /*====================*/
59 return((ulint
)GetCurrentProcessId());
61 return((ulint
)getpid());
65 /****************************************************************//**
66 Allocates large pages memory.
67 @return allocated memory */
72 ulint
* n
) /*!< in/out: number of bytes */
76 #if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
80 if (!os_use_large_pages
|| !os_large_page_size
) {
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),
89 shmid
= shmget(IPC_PRIVATE
, (size_t)size
, SHM_HUGETLB
| SHM_R
| SHM_W
);
91 fprintf(stderr
, "InnoDB: HugeTLB: Warning: Failed to allocate"
92 " %lu bytes. errno %d\n", size
, errno
);
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",
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 UNIV_MEM_ALLOC(ptr
, size
);
118 fprintf(stderr
, "InnoDB HugeTLB: Warning: Using conventional"
121 #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
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
,
136 fprintf(stderr
, "InnoDB: VirtualAlloc(%lu bytes) failed;"
137 " Windows error %lu\n",
138 (ulong
) size
, (ulong
) GetLastError());
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
147 ptr
= ut_malloc_low(size
, TRUE
, FALSE
);
149 # ifdef HAVE_GETPAGESIZE
150 size
= getpagesize();
152 size
= UNIV_PAGE_SIZE
;
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;"
162 (ulong
) size
, (ulong
) errno
);
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
);
174 /****************************************************************//**
175 Frees large pages memory. */
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
);
198 #endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
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());
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
216 if (munmap(ptr
, size
)) {
217 fprintf(stderr
, "InnoDB: munmap(%p, %lu) failed;"
219 ptr
, (ulong
) size
, (ulong
) errno
);
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
);