📄 os0thread.c
字号:
/******************************************************The interface to the operating system thread control primitives(c) 1995 Innobase OyCreated 9/8/1995 Heikki Tuuri*******************************************************/#include "os0thread.h"#ifdef UNIV_NONINL#include "os0thread.ic"#endif#ifdef __WIN__#include <windows.h>#endif#include "srv0srv.h"#include "os0sync.h"/*******************************************************************Compares two thread ids for equality. */iboolos_thread_eq(/*=========*/ /* out: TRUE if equal */ os_thread_id_t a, /* in: OS thread or thread id */ os_thread_id_t b) /* in: OS thread or thread id */{#ifdef __WIN__ if (a == b) { return(TRUE); } return(FALSE);#else if (pthread_equal(a, b)) { return(TRUE); } return(FALSE);#endif}/********************************************************************Converts an OS thread id to a ulint. It is NOT guaranteed that the ulint isunique for the thread though! */ulintos_thread_pf(/*=========*/ os_thread_id_t a){#ifdef UNIV_HPUX10 /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2, field3. We do not know if field1 determines the thread uniquely. */ return((ulint)(a.field1));#else return((ulint)a);#endif}/*********************************************************************Returns the thread identifier of current thread. Currently the threadidentifier in Unix is the thread handle itself. Note that in HP-UXpthread_t is a struct of 3 fields. */os_thread_id_tos_thread_get_curr_id(void)/*=======================*/{#ifdef __WIN__ return(GetCurrentThreadId());#else return(pthread_self());#endif}/********************************************************************Creates a new thread of execution. The execution starts fromthe function given. The start function takes a void* parameterand returns an ulint. */os_thread_tos_thread_create(/*=============*/ /* out: handle to the thread */#ifndef __WIN__ os_posix_f_t start_f,#else ulint (*start_f)(void*), /* in: pointer to function from which to start */#endif void* arg, /* in: argument to start function */ os_thread_id_t* thread_id) /* out: id of the created thread */{#ifdef __WIN__ os_thread_t thread; DWORD win_thread_id; os_mutex_enter(os_sync_mutex); os_thread_count++; os_mutex_exit(os_sync_mutex); thread = CreateThread(NULL, /* no security attributes */ 0, /* default size stack */ (LPTHREAD_START_ROUTINE)start_f, arg, 0, /* thread runs immediately */ &win_thread_id); if (srv_set_thread_priorities) { /* Set created thread priority the same as a normal query in MYSQL: we try to prevent starvation of threads by assigning same priority QUERY_PRIOR to all */ ut_a(SetThreadPriority(thread, srv_query_thread_priority)); } *thread_id = win_thread_id; return(thread);#else int ret; os_thread_t pthread; pthread_attr_t attr;#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)) pthread_attr_init(&attr);#endif #ifdef UNIV_AIX /* We must make sure a thread stack is at least 32 kB, otherwise InnoDB might crash; we do not know if the default stack size on AIX is always big enough. An empirical test on AIX-4.3 suggested the size was 96 kB, though. */ ret = pthread_attr_setstacksize(&attr, (size_t)(PTHREAD_STACK_MIN + 32 * 1024)); if (ret) { fprintf(stderr, "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret); exit(1); }#endif#ifdef __NETWARE__ ret = pthread_attr_setstacksize(&attr, (size_t) NW_THD_STACKSIZE); if (ret) { fprintf(stderr, "InnoDB: Error: pthread_attr_setstacksize returned %d\n", ret); exit(1); }#endif os_mutex_enter(os_sync_mutex); os_thread_count++; os_mutex_exit(os_sync_mutex);#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10) ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);#else ret = pthread_create(&pthread, &attr, start_f, arg);#endif if (ret) { fprintf(stderr, "InnoDB: Error: pthread_create returned %d\n", ret); exit(1); }#if !(defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)) pthread_attr_destroy(&attr);#endif if (srv_set_thread_priorities) { my_pthread_setprio(pthread, srv_query_thread_priority); } *thread_id = pthread; return(pthread);#endif}/*********************************************************************Exits the current thread. */voidos_thread_exit(/*===========*/ void* exit_value) /* in: exit value; in Windows this void* is cast as a DWORD */{#ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Thread exits, id %lu\n", os_thread_pf(os_thread_get_curr_id()));#endif os_mutex_enter(os_sync_mutex); os_thread_count--; os_mutex_exit(os_sync_mutex);#ifdef __WIN__ ExitThread((DWORD)exit_value);#else pthread_exit(exit_value);#endif}#ifdef HAVE_PTHREAD_JOINintos_thread_join(/*=============*/ os_thread_id_t thread_id) /* in: id of the thread to join */{ return pthread_join(thread_id, NULL);}#endif/*********************************************************************Returns handle to the current thread. */os_thread_tos_thread_get_curr(void)/*====================*/{#ifdef __WIN__ return(GetCurrentThread());#else return(pthread_self());#endif} /*********************************************************************Advises the os to give up remainder of the thread's time slice. */voidos_thread_yield(void)/*=================*/{#if defined(__WIN__) Sleep(0);#elif (defined(HAVE_SCHED_YIELD) && defined(HAVE_SCHED_H)) sched_yield();#elif defined(HAVE_PTHREAD_YIELD_ZERO_ARG) pthread_yield();#elif defined(HAVE_PTHREAD_YIELD_ONE_ARG) pthread_yield(0);#else os_thread_sleep(0);#endif}/*********************************************************************The thread sleeps at least the time given in microseconds. */voidos_thread_sleep(/*============*/ ulint tm) /* in: time in microseconds */{#ifdef __WIN__ Sleep((DWORD) tm / 1000);#elif defined(__NETWARE__) delay(tm / 1000);#else struct timeval t; t.tv_sec = tm / 1000000; t.tv_usec = tm % 1000000; select(0, NULL, NULL, NULL, &t);#endif}/**********************************************************************Sets a thread priority. */voidos_thread_set_priority(/*===================*/ os_thread_t handle, /* in: OS handle to the thread */ ulint pri) /* in: priority */{#ifdef __WIN__ int os_pri; if (pri == OS_THREAD_PRIORITY_BACKGROUND) { os_pri = THREAD_PRIORITY_BELOW_NORMAL; } else if (pri == OS_THREAD_PRIORITY_NORMAL) { os_pri = THREAD_PRIORITY_NORMAL; } else if (pri == OS_THREAD_PRIORITY_ABOVE_NORMAL) { os_pri = THREAD_PRIORITY_HIGHEST; } else { ut_error; } ut_a(SetThreadPriority(handle, os_pri));#else UT_NOT_USED(handle); UT_NOT_USED(pri);#endif}/**********************************************************************Gets a thread priority. */ulintos_thread_get_priority(/*===================*/ /* out: priority */ os_thread_t handle __attribute__((unused))) /* in: OS handle to the thread */{#ifdef __WIN__ int os_pri; ulint pri; os_pri = GetThreadPriority(handle); if (os_pri == THREAD_PRIORITY_BELOW_NORMAL) { pri = OS_THREAD_PRIORITY_BACKGROUND; } else if (os_pri == THREAD_PRIORITY_NORMAL) { pri = OS_THREAD_PRIORITY_NORMAL; } else if (os_pri == THREAD_PRIORITY_HIGHEST) { pri = OS_THREAD_PRIORITY_ABOVE_NORMAL; } else { ut_error; } return(pri);#else return(0);#endif}/**********************************************************************Gets the last operating system error code for the calling thread. */ulintos_thread_get_last_error(void)/*==========================*/{#ifdef __WIN__ return(GetLastError());#else return(0);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -