~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/os/os0proc.cc

code clean move Item_func_ascii, Item_func_bit_count, Item_func_find_in_set, Item_func_ord  to functions directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
4
 
 
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.
8
 
 
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.
12
 
 
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
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file os/os0proc.c
21
 
The interface to the operating system
22
 
process control primitives
23
 
 
24
 
Created 9/30/1995 Heikki Tuuri
25
 
*******************************************************/
26
 
 
27
 
#include "os0proc.h"
28
 
#ifdef UNIV_NONINL
29
 
#include "os0proc.ic"
30
 
#endif
31
 
 
32
 
#include "ut0mem.h"
33
 
#include "ut0byte.h"
34
 
#include <errno.h>
35
 
#include <unistd.h>
36
 
 
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
43
 
#endif
44
 
 
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;
48
 
 
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 */
55
 
UNIV_INTERN
56
 
ulint
57
 
os_proc_get_number(void)
58
 
/*====================*/
59
 
{
60
 
#ifdef __WIN__
61
 
        return((ulint)GetCurrentProcessId());
62
 
#else
63
 
        return((ulint)getpid());
64
 
#endif
65
 
}
66
 
 
67
 
/****************************************************************//**
68
 
Allocates large pages memory.
69
 
@return allocated memory */
70
 
UNIV_INTERN
71
 
void*
72
 
os_mem_alloc_large(
73
 
/*===============*/
74
 
        ulint*  n)                      /*!< in/out: number of bytes */
75
 
{
76
 
        void*   ptr;
77
 
        ulint   size;
78
 
#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
79
 
        int shmid;
80
 
        struct shmid_ds buf;
81
 
 
82
 
        if (!os_use_large_pages || !os_large_page_size) {
83
 
                goto skip;
84
 
        }
85
 
 
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),
89
 
                             os_large_page_size);
90
 
 
91
 
        shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
92
 
        if (shmid < 0) {
93
 
                fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
94
 
                        " %lu bytes. errno %d\n", size, errno);
95
 
                ptr = NULL;
96
 
        } else {
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",
101
 
                                errno);
102
 
                        ptr = NULL;
103
 
                }
104
 
 
105
 
                /* Remove the shared memory segment so that it will be
106
 
                automatically freed after memory is detached or
107
 
                process exits */
108
 
                shmctl(shmid, IPC_RMID, &buf);
109
 
        }
110
 
 
111
 
        if (ptr) {
112
 
                *n = size;
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);
118
 
# endif
119
 
                UNIV_MEM_ALLOC(ptr, size);
120
 
                return(ptr);
121
 
        }
122
 
 
123
 
        fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
124
 
                " memory pool\n");
125
 
skip:
126
 
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
127
 
 
128
 
#ifdef __WIN__
129
 
        SYSTEM_INFO     system_info;
130
 
        GetSystemInfo(&system_info);
131
 
 
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,
139
 
                           PAGE_READWRITE);
140
 
        if (!ptr) {
141
 
                fprintf(stderr, "InnoDB: VirtualAlloc(%lu bytes) failed;"
142
 
                        " Windows error %lu\n",
143
 
                        (ulong) size, (ulong) GetLastError());
144
 
        } else {
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);
149
 
        }
150
 
#elif !defined OS_MAP_ANON
151
 
        size = *n;
152
 
        ptr = ut_malloc_low(size, TRUE, FALSE);
153
 
#else
154
 
# ifdef HAVE_GETPAGESIZE
155
 
        size = getpagesize();
156
 
# else
157
 
        size = UNIV_PAGE_SIZE;
158
 
# endif
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;"
166
 
                        " errno %lu\n",
167
 
                        (ulong) size, (ulong) errno);
168
 
                ptr = NULL;
169
 
        } else {
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);
174
 
        }
175
 
#endif
176
 
        return(ptr);
177
 
}
178
 
 
179
 
/****************************************************************//**
180
 
Frees large pages memory. */
181
 
UNIV_INTERN
182
 
void
183
 
os_mem_free_large(
184
 
/*==============*/
185
 
        void    *ptr,                   /*!< in: pointer returned by
186
 
                                        os_mem_alloc_large() */
187
 
        ulint   size)                   /*!< in: size returned by
188
 
                                        os_mem_alloc_large() */
189
 
{
190
 
        os_fast_mutex_lock(&ut_list_mutex);
191
 
        ut_a(ut_total_allocated_memory >= size);
192
 
        os_fast_mutex_unlock(&ut_list_mutex);
193
 
 
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);
201
 
                return;
202
 
        }
203
 
#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
204
 
#ifdef __WIN__
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());
211
 
        } else {
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);
217
 
        }
218
 
#elif !defined OS_MAP_ANON
219
 
        ut_free(ptr);
220
 
#else
221
 
        if (munmap(static_cast<char *>(ptr), size)) {
222
 
                fprintf(stderr, "InnoDB: munmap(%p, %lu) failed;"
223
 
                        " errno %lu\n",
224
 
                        ptr, (ulong) size, (ulong) errno);
225
 
        } else {
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);
231
 
        }
232
 
#endif
233
 
}