Drizzled Public API Documentation

os0thread.cc
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., 51 Franklin
15 St, Fifth Floor, Boston, MA 02110-1301 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "os0thread.h"
27 #ifdef UNIV_NONINL
28 #include "os0thread.ic"
29 #endif
30 
31 #ifdef __WIN__
32 #include <windows.h>
33 #else
34 #include <sys/select.h>
35 #endif
36 
37 #ifndef UNIV_HOTBACKUP
38 #include "srv0srv.h"
39 #include "os0sync.h"
40 
41 /***************************************************************/
44 UNIV_INTERN
45 ibool
47 /*=========*/
48  os_thread_id_t a,
49  os_thread_id_t b)
50 {
51 #ifdef __WIN__
52  if (a == b) {
53  return(TRUE);
54  }
55 
56  return(FALSE);
57 #else
58  if (pthread_equal(a, b)) {
59  return(TRUE);
60  }
61 
62  return(FALSE);
63 #endif
64 }
65 
66 /****************************************************************/
70 UNIV_INTERN
71 ulint
73 /*=========*/
74  os_thread_id_t a)
75 {
76 #ifdef UNIV_HPUX10
77  /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2,
78  field3. We do not know if field1 determines the thread uniquely. */
79 
80  return((ulint)(a.field1));
81 #else
82  return((ulint)a);
83 #endif
84 }
85 
86 /*****************************************************************/
91 UNIV_INTERN
94 /*=======================*/
95 {
96 #ifdef __WIN__
97  return(GetCurrentThreadId());
98 #else
99  return(pthread_self());
100 #endif
101 }
102 
103 /****************************************************************/
108 UNIV_INTERN
109 os_thread_t
111 /*=============*/
112 #ifndef __WIN__
113  os_posix_f_t start_f,
114 #else
115  ulint (*start_f)(void*),
117 #endif
118  void* arg,
120  os_thread_id_t* thread_id)
122 {
123 #ifdef __WIN__
124  os_thread_t thread;
125  DWORD win_thread_id;
126 
128  os_thread_count++;
130 
131  thread = CreateThread(NULL, /* no security attributes */
132  0, /* default size stack */
133  (LPTHREAD_START_ROUTINE)start_f,
134  arg,
135  0, /* thread runs immediately */
136  &win_thread_id);
137 
138  if (thread_id) {
139  *thread_id = win_thread_id;
140  }
141 
142  return(thread);
143 #else
144  int ret;
145  os_thread_t pthread;
146  pthread_attr_t attr;
147 
148 #ifndef UNIV_HPUX10
149  pthread_attr_init(&attr);
150 #endif
151 
152 #ifdef UNIV_AIX
153  /* We must make sure a thread stack is at least 32 kB, otherwise
154  InnoDB might crash; we do not know if the default stack size on
155  AIX is always big enough. An empirical test on AIX-4.3 suggested
156  the size was 96 kB, though. */
157 
158  ret = pthread_attr_setstacksize(&attr,
159  (size_t)(PTHREAD_STACK_MIN
160  + 32 * 1024));
161  if (ret) {
162  fprintf(stderr,
163  "InnoDB: Error: pthread_attr_setstacksize"
164  " returned %d\n", ret);
165  exit(1);
166  }
167 #endif
169  os_thread_count++;
171 
172 #ifdef UNIV_HPUX10
173  ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
174 #else
175  ret = pthread_create(&pthread, &attr, start_f, arg);
176 #endif
177  if (ret) {
178  fprintf(stderr,
179  "InnoDB: Error: pthread_create returned %d\n", ret);
180  exit(1);
181  }
182 
183 #ifndef UNIV_HPUX10
184  pthread_attr_destroy(&attr);
185 #endif
186 
187  if (thread_id) {
188  *thread_id = pthread;
189  }
190 
191  return(pthread);
192 #endif
193 }
194 
195 /*****************************************************************/
197 UNIV_INTERN
198 void
200 /*===========*/
201  void* exit_value)
203 {
204 #ifdef UNIV_DEBUG_THREAD_CREATION
205  fprintf(stderr, "Thread exits, id %lu\n",
207 #endif
208 
209 #ifdef UNIV_PFS_THREAD
210  pfs_delete_thread();
211 #endif
212 
214  os_thread_count--;
216 
217 #ifdef __WIN__
218  ExitThread((DWORD)exit_value);
219 #else
220  pthread_detach(pthread_self());
221  pthread_exit(exit_value);
222 #endif
223 }
224 
225 /*****************************************************************/
228 UNIV_INTERN
229 os_thread_t
231 /*====================*/
232 {
233 #ifdef __WIN__
234  return(GetCurrentThread());
235 #else
236  return(pthread_self());
237 #endif
238 }
239 
240 /*****************************************************************/
242 UNIV_INTERN
243 void
245 /*=================*/
246 {
247 #if defined(__WIN__)
248  SwitchToThread();
249 #elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H))
250  sched_yield();
251 #elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
252  pthread_yield();
253 #elif defined(HAVE_PTHREAD_YIELD_ONE_ARG)
254  pthread_yield(0);
255 #else
256  os_thread_sleep(0);
257 #endif
258 }
259 #endif /* !UNIV_HOTBACKUP */
260 
261 /*****************************************************************/
263 UNIV_INTERN
264 void
266 /*============*/
267  ulint tm)
268 {
269 #ifdef __WIN__
270  Sleep((DWORD) tm / 1000);
271 #else
272  struct timeval t;
273 
274  t.tv_sec = tm / 1000000;
275  t.tv_usec = tm % 1000000;
276 
277  select(0, NULL, NULL, NULL, &t);
278 #endif
279 }
280 
281 #ifndef UNIV_HOTBACKUP
282 /******************************************************************/
284 UNIV_INTERN
285 void
287 /*===================*/
288  os_thread_t handle,
289  ulint pri)
290 {
291 #ifdef __WIN__
292  int os_pri;
293 
294  if (pri == OS_THREAD_PRIORITY_BACKGROUND) {
295  os_pri = THREAD_PRIORITY_BELOW_NORMAL;
296  } else if (pri == OS_THREAD_PRIORITY_NORMAL) {
297  os_pri = THREAD_PRIORITY_NORMAL;
298  } else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) {
299  os_pri = THREAD_PRIORITY_HIGHEST;
300  } else {
301  ut_error;
302  }
303 
304  ut_a(SetThreadPriority(handle, os_pri));
305 #else
306  UT_NOT_USED(handle);
307  UT_NOT_USED(pri);
308 #endif
309 }
310 
311 /******************************************************************/
314 UNIV_INTERN
315 ulint
317 /*===================*/
318  os_thread_t /*handle __attribute__((unused))*/)
320 {
321 #ifdef __WIN__
322  int os_pri;
323  ulint pri;
324 
325  os_pri = GetThreadPriority(handle);
326 
327  if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) {
328  pri = OS_THREAD_PRIORITY_BACKGROUND;
329  } else if (os_pri == THREAD_PRIORITY_NORMAL) {
330  pri = OS_THREAD_PRIORITY_NORMAL;
331  } else if (os_pri == THREAD_PRIORITY_HIGHEST) {
332  pri = OS_THREAD_PRIORITY_ABOVE_NORMAL;
333  } else {
334  ut_error;
335  }
336 
337  return(pri);
338 #else
339  return(0);
340 #endif
341 }
342 
343 /******************************************************************/
346 UNIV_INTERN
347 ulint
349 /*==========================*/
350 {
351 #ifdef __WIN__
352  return(GetLastError());
353 #else
354  return(0);
355 #endif
356 }
357 #endif /* !UNIV_HOTBACKUP */