00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include "os0thread.h"
00027 #ifdef UNIV_NONINL
00028 #include "os0thread.ic"
00029 #endif
00030
00031 #ifdef __WIN__
00032 #include <windows.h>
00033 #else
00034 #include <sys/select.h>
00035 #endif
00036
00037 #ifndef UNIV_HOTBACKUP
00038 #include "srv0srv.h"
00039 #include "os0sync.h"
00040
00041
00044 UNIV_INTERN
00045 ibool
00046 os_thread_eq(
00047
00048 os_thread_id_t a,
00049 os_thread_id_t b)
00050 {
00051 #ifdef __WIN__
00052 if (a == b) {
00053 return(TRUE);
00054 }
00055
00056 return(FALSE);
00057 #else
00058 if (pthread_equal(a, b)) {
00059 return(TRUE);
00060 }
00061
00062 return(FALSE);
00063 #endif
00064 }
00065
00066
00070 UNIV_INTERN
00071 ulint
00072 os_thread_pf(
00073
00074 os_thread_id_t a)
00075 {
00076 #ifdef UNIV_HPUX10
00077
00078
00079
00080 return((ulint)(a.field1));
00081 #else
00082 return((ulint)a);
00083 #endif
00084 }
00085
00086
00091 UNIV_INTERN
00092 os_thread_id_t
00093 os_thread_get_curr_id(void)
00094
00095 {
00096 #ifdef __WIN__
00097 return(GetCurrentThreadId());
00098 #else
00099 return(pthread_self());
00100 #endif
00101 }
00102
00103
00108 UNIV_INTERN
00109 os_thread_t
00110 os_thread_create(
00111
00112 #ifndef __WIN__
00113 os_posix_f_t start_f,
00114 #else
00115 ulint (*start_f)(void*),
00117 #endif
00118 void* arg,
00120 os_thread_id_t* thread_id)
00122 {
00123 #ifdef __WIN__
00124 os_thread_t thread;
00125 DWORD win_thread_id;
00126
00127 os_mutex_enter(os_sync_mutex);
00128 os_thread_count++;
00129 os_mutex_exit(os_sync_mutex);
00130
00131 thread = CreateThread(NULL,
00132 0,
00133 (LPTHREAD_START_ROUTINE)start_f,
00134 arg,
00135 0,
00136 &win_thread_id);
00137
00138 if (thread_id) {
00139 *thread_id = win_thread_id;
00140 }
00141
00142 return(thread);
00143 #else
00144 int ret;
00145 os_thread_t pthread;
00146 pthread_attr_t attr;
00147
00148 #ifndef UNIV_HPUX10
00149 pthread_attr_init(&attr);
00150 #endif
00151
00152 #ifdef UNIV_AIX
00153
00154
00155
00156
00157
00158 ret = pthread_attr_setstacksize(&attr,
00159 (size_t)(PTHREAD_STACK_MIN
00160 + 32 * 1024));
00161 if (ret) {
00162 fprintf(stderr,
00163 "InnoDB: Error: pthread_attr_setstacksize"
00164 " returned %d\n", ret);
00165 exit(1);
00166 }
00167 #endif
00168 os_mutex_enter(os_sync_mutex);
00169 os_thread_count++;
00170 os_mutex_exit(os_sync_mutex);
00171
00172 #ifdef UNIV_HPUX10
00173 ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
00174 #else
00175 ret = pthread_create(&pthread, &attr, start_f, arg);
00176 #endif
00177 if (ret) {
00178 fprintf(stderr,
00179 "InnoDB: Error: pthread_create returned %d\n", ret);
00180 exit(1);
00181 }
00182
00183 #ifndef UNIV_HPUX10
00184 pthread_attr_destroy(&attr);
00185 #endif
00186
00187 if (thread_id) {
00188 *thread_id = pthread;
00189 }
00190
00191 return(pthread);
00192 #endif
00193 }
00194
00195
00197 UNIV_INTERN
00198 void
00199 os_thread_exit(
00200
00201 void* exit_value)
00203 {
00204 #ifdef UNIV_DEBUG_THREAD_CREATION
00205 fprintf(stderr, "Thread exits, id %lu\n",
00206 os_thread_pf(os_thread_get_curr_id()));
00207 #endif
00208
00209 #ifdef UNIV_PFS_THREAD
00210 pfs_delete_thread();
00211 #endif
00212
00213 os_mutex_enter(os_sync_mutex);
00214 os_thread_count--;
00215 os_mutex_exit(os_sync_mutex);
00216
00217 #ifdef __WIN__
00218 ExitThread((DWORD)exit_value);
00219 #else
00220 pthread_detach(pthread_self());
00221 pthread_exit(exit_value);
00222 #endif
00223 }
00224
00225
00228 UNIV_INTERN
00229 os_thread_t
00230 os_thread_get_curr(void)
00231
00232 {
00233 #ifdef __WIN__
00234 return(GetCurrentThread());
00235 #else
00236 return(pthread_self());
00237 #endif
00238 }
00239
00240
00242 UNIV_INTERN
00243 void
00244 os_thread_yield(void)
00245
00246 {
00247 #if defined(__WIN__)
00248 SwitchToThread();
00249 #elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H))
00250 sched_yield();
00251 #elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
00252 pthread_yield();
00253 #elif defined(HAVE_PTHREAD_YIELD_ONE_ARG)
00254 pthread_yield(0);
00255 #else
00256 os_thread_sleep(0);
00257 #endif
00258 }
00259 #endif
00260
00261
00263 UNIV_INTERN
00264 void
00265 os_thread_sleep(
00266
00267 ulint tm)
00268 {
00269 #ifdef __WIN__
00270 Sleep((DWORD) tm / 1000);
00271 #else
00272 struct timeval t;
00273
00274 t.tv_sec = tm / 1000000;
00275 t.tv_usec = tm % 1000000;
00276
00277 select(0, NULL, NULL, NULL, &t);
00278 #endif
00279 }
00280
00281 #ifndef UNIV_HOTBACKUP
00282
00284 UNIV_INTERN
00285 void
00286 os_thread_set_priority(
00287
00288 os_thread_t handle,
00289 ulint pri)
00290 {
00291 #ifdef __WIN__
00292 int os_pri;
00293
00294 if (pri == OS_THREAD_PRIORITY_BACKGROUND) {
00295 os_pri = THREAD_PRIORITY_BELOW_NORMAL;
00296 } else if (pri == OS_THREAD_PRIORITY_NORMAL) {
00297 os_pri = THREAD_PRIORITY_NORMAL;
00298 } else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) {
00299 os_pri = THREAD_PRIORITY_HIGHEST;
00300 } else {
00301 ut_error;
00302 }
00303
00304 ut_a(SetThreadPriority(handle, os_pri));
00305 #else
00306 UT_NOT_USED(handle);
00307 UT_NOT_USED(pri);
00308 #endif
00309 }
00310
00311
00314 UNIV_INTERN
00315 ulint
00316 os_thread_get_priority(
00317
00318 os_thread_t )
00320 {
00321 #ifdef __WIN__
00322 int os_pri;
00323 ulint pri;
00324
00325 os_pri = GetThreadPriority(handle);
00326
00327 if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) {
00328 pri = OS_THREAD_PRIORITY_BACKGROUND;
00329 } else if (os_pri == THREAD_PRIORITY_NORMAL) {
00330 pri = OS_THREAD_PRIORITY_NORMAL;
00331 } else if (os_pri == THREAD_PRIORITY_HIGHEST) {
00332 pri = OS_THREAD_PRIORITY_ABOVE_NORMAL;
00333 } else {
00334 ut_error;
00335 }
00336
00337 return(pri);
00338 #else
00339 return(0);
00340 #endif
00341 }
00342
00343
00346 UNIV_INTERN
00347 ulint
00348 os_thread_get_last_error(void)
00349
00350 {
00351 #ifdef __WIN__
00352 return(GetLastError());
00353 #else
00354 return(0);
00355 #endif
00356 }
00357 #endif