~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to storage/innobase/os/os0thread.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2011-11-08 11:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20111108113113-3ulw01fvi4vn8m25
Tags: upstream-5.5.17
ImportĀ upstreamĀ versionĀ 5.5.17

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1995, 2010, 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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file os/os0thread.c
 
21
The interface to the operating system thread control primitives
 
22
 
 
23
Created 9/8/1995 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#include "os0thread.h"
 
27
#ifdef UNIV_NONINL
 
28
#include "os0thread.ic"
 
29
#endif
 
30
 
 
31
#ifdef __WIN__
 
32
#include <windows.h>
 
33
#endif
 
34
 
 
35
#ifndef UNIV_HOTBACKUP
 
36
#include "srv0srv.h"
 
37
#include "os0sync.h"
 
38
 
 
39
/***************************************************************//**
 
40
Compares two thread ids for equality.
 
41
@return TRUE if equal */
 
42
UNIV_INTERN
 
43
ibool
 
44
os_thread_eq(
 
45
/*=========*/
 
46
        os_thread_id_t  a,      /*!< in: OS thread or thread id */
 
47
        os_thread_id_t  b)      /*!< in: OS thread or thread id */
 
48
{
 
49
#ifdef __WIN__
 
50
        if (a == b) {
 
51
                return(TRUE);
 
52
        }
 
53
 
 
54
        return(FALSE);
 
55
#else
 
56
        if (pthread_equal(a, b)) {
 
57
                return(TRUE);
 
58
        }
 
59
 
 
60
        return(FALSE);
 
61
#endif
 
62
}
 
63
 
 
64
/****************************************************************//**
 
65
Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint is
 
66
unique for the thread though!
 
67
@return thread identifier as a number */
 
68
UNIV_INTERN
 
69
ulint
 
70
os_thread_pf(
 
71
/*=========*/
 
72
        os_thread_id_t  a)      /*!< in: OS thread identifier */
 
73
{
 
74
#ifdef UNIV_HPUX10
 
75
        /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2,
 
76
        field3. We do not know if field1 determines the thread uniquely. */
 
77
 
 
78
        return((ulint)(a.field1));
 
79
#else
 
80
        return((ulint)a);
 
81
#endif
 
82
}
 
83
 
 
84
/*****************************************************************//**
 
85
Returns the thread identifier of current thread. Currently the thread
 
86
identifier in Unix is the thread handle itself. Note that in HP-UX
 
87
pthread_t is a struct of 3 fields.
 
88
@return current thread identifier */
 
89
UNIV_INTERN
 
90
os_thread_id_t
 
91
os_thread_get_curr_id(void)
 
92
/*=======================*/
 
93
{
 
94
#ifdef __WIN__
 
95
        return(GetCurrentThreadId());
 
96
#else
 
97
        return(pthread_self());
 
98
#endif
 
99
}
 
100
 
 
101
/****************************************************************//**
 
102
Creates a new thread of execution. The execution starts from
 
103
the function given. The start function takes a void* parameter
 
104
and returns an ulint.
 
105
@return handle to the thread */
 
106
UNIV_INTERN
 
107
os_thread_t
 
108
os_thread_create(
 
109
/*=============*/
 
110
#ifndef __WIN__
 
111
        os_posix_f_t            start_f,
 
112
#else
 
113
        ulint (*start_f)(void*),                /*!< in: pointer to function
 
114
                                                from which to start */
 
115
#endif
 
116
        void*                   arg,            /*!< in: argument to start
 
117
                                                function */
 
118
        os_thread_id_t*         thread_id)      /*!< out: id of the created
 
119
                                                thread, or NULL */
 
120
{
 
121
#ifdef __WIN__
 
122
        os_thread_t     thread;
 
123
        DWORD           win_thread_id;
 
124
 
 
125
        os_mutex_enter(os_sync_mutex);
 
126
        os_thread_count++;
 
127
        os_mutex_exit(os_sync_mutex);
 
128
 
 
129
        thread = CreateThread(NULL,     /* no security attributes */
 
130
                              0,        /* default size stack */
 
131
                              (LPTHREAD_START_ROUTINE)start_f,
 
132
                              arg,
 
133
                              0,        /* thread runs immediately */
 
134
                              &win_thread_id);
 
135
 
 
136
        if (thread_id) {
 
137
                *thread_id = win_thread_id;
 
138
        }
 
139
 
 
140
        return(thread);
 
141
#else
 
142
        int             ret;
 
143
        os_thread_t     pthread;
 
144
        pthread_attr_t  attr;
 
145
 
 
146
#ifndef UNIV_HPUX10
 
147
        pthread_attr_init(&attr);
 
148
#endif
 
149
 
 
150
#ifdef UNIV_AIX
 
151
        /* We must make sure a thread stack is at least 32 kB, otherwise
 
152
        InnoDB might crash; we do not know if the default stack size on
 
153
        AIX is always big enough. An empirical test on AIX-4.3 suggested
 
154
        the size was 96 kB, though. */
 
155
 
 
156
        ret = pthread_attr_setstacksize(&attr,
 
157
                                        (size_t)(PTHREAD_STACK_MIN
 
158
                                                 + 32 * 1024));
 
159
        if (ret) {
 
160
                fprintf(stderr,
 
161
                        "InnoDB: Error: pthread_attr_setstacksize"
 
162
                        " returned %d\n", ret);
 
163
                exit(1);
 
164
        }
 
165
#endif
 
166
        os_mutex_enter(os_sync_mutex);
 
167
        os_thread_count++;
 
168
        os_mutex_exit(os_sync_mutex);
 
169
 
 
170
#ifdef UNIV_HPUX10
 
171
        ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
 
172
#else
 
173
        ret = pthread_create(&pthread, &attr, start_f, arg);
 
174
#endif
 
175
        if (ret) {
 
176
                fprintf(stderr,
 
177
                        "InnoDB: Error: pthread_create returned %d\n", ret);
 
178
                exit(1);
 
179
        }
 
180
 
 
181
#ifndef UNIV_HPUX10
 
182
        pthread_attr_destroy(&attr);
 
183
#endif
 
184
        if (thread_id) {
 
185
                *thread_id = pthread;
 
186
        }
 
187
 
 
188
        return(pthread);
 
189
#endif
 
190
}
 
191
 
 
192
/*****************************************************************//**
 
193
Exits the current thread. */
 
194
UNIV_INTERN
 
195
void
 
196
os_thread_exit(
 
197
/*===========*/
 
198
        void*   exit_value)     /*!< in: exit value; in Windows this void*
 
199
                                is cast as a DWORD */
 
200
{
 
201
#ifdef UNIV_DEBUG_THREAD_CREATION
 
202
        fprintf(stderr, "Thread exits, id %lu\n",
 
203
                os_thread_pf(os_thread_get_curr_id()));
 
204
#endif
 
205
 
 
206
#ifdef UNIV_PFS_THREAD
 
207
        pfs_delete_thread();
 
208
#endif
 
209
 
 
210
        os_mutex_enter(os_sync_mutex);
 
211
        os_thread_count--;
 
212
        os_mutex_exit(os_sync_mutex);
 
213
 
 
214
#ifdef __WIN__
 
215
        ExitThread((DWORD)exit_value);
 
216
#else
 
217
        pthread_detach(pthread_self());
 
218
        pthread_exit(exit_value);
 
219
#endif
 
220
}
 
221
 
 
222
/*****************************************************************//**
 
223
Advises the os to give up remainder of the thread's time slice. */
 
224
UNIV_INTERN
 
225
void
 
226
os_thread_yield(void)
 
227
/*=================*/
 
228
{
 
229
#if defined(__WIN__)
 
230
        SwitchToThread();
 
231
#elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H))
 
232
        sched_yield();
 
233
#elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
 
234
        pthread_yield();
 
235
#elif defined(HAVE_PTHREAD_YIELD_ONE_ARG)
 
236
        pthread_yield(0);
 
237
#else
 
238
        os_thread_sleep(0);
 
239
#endif
 
240
}
 
241
#endif /* !UNIV_HOTBACKUP */
 
242
 
 
243
/*****************************************************************//**
 
244
The thread sleeps at least the time given in microseconds. */
 
245
UNIV_INTERN
 
246
void
 
247
os_thread_sleep(
 
248
/*============*/
 
249
        ulint   tm)     /*!< in: time in microseconds */
 
250
{
 
251
#ifdef __WIN__
 
252
        Sleep((DWORD) tm / 1000);
 
253
#else
 
254
        struct timeval  t;
 
255
 
 
256
        t.tv_sec = tm / 1000000;
 
257
        t.tv_usec = tm % 1000000;
 
258
 
 
259
        select(0, NULL, NULL, NULL, &t);
 
260
#endif
 
261
}