12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
Functions to handle initializating and allocationg of all mysys & debug
23
#include "drizzled/internal/my_sys.h"
24
#include "drizzled/internal/thread_var.h"
25
#include "drizzled/internal/m_string.h"
21
#include "mysys/mysys_priv.h"
22
#include <mysys/my_pthread.h>
23
#include <mystrings/m_string.h>
28
26
#include <signal.h>
30
28
#if TIME_WITH_SYS_TIME
41
#include <boost/thread/thread.hpp>
42
#include <boost/thread/mutex.hpp>
43
#include <boost/thread/tss.hpp>
50
boost::thread_specific_ptr<st_my_thread_var> THR_KEY_mysys;
51
boost::mutex THR_LOCK_threads;
39
uint32_t thd_lib_detected= 0;
41
pthread_key_t THR_KEY_mysys;
42
pthread_mutex_t THR_LOCK_lock;
43
pthread_mutex_t THR_LOCK_threads;
44
pthread_cond_t THR_COND_threads;
45
uint32_t THR_thread_count= 0;
46
uint32_t my_thread_end_wait_time= 5;
47
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
48
pthread_mutexattr_t my_fast_mutexattr;
50
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
51
pthread_mutexattr_t my_errorcheck_mutexattr;
55
static uint32_t get_thread_lib(void);
54
58
initialize thread environment
64
68
bool my_thread_global_init(void)
71
thd_lib_detected= get_thread_lib();
73
if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
75
fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
79
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
81
Set mutex type to "fast" a.k.a "adaptive"
83
In this case the thread may steal the mutex from some other thread
84
that is waiting for the same mutex. This will save us some
85
context switches but may cause a thread to 'starve forever' while
86
waiting for the mutex (not likely if the code within the mutex is
89
pthread_mutexattr_init(&my_fast_mutexattr);
90
pthread_mutexattr_settype(&my_fast_mutexattr,
91
PTHREAD_MUTEX_ADAPTIVE_NP);
93
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
95
Set mutex type to "errorcheck"
97
pthread_mutexattr_init(&my_errorcheck_mutexattr);
98
pthread_mutexattr_settype(&my_errorcheck_mutexattr,
99
PTHREAD_MUTEX_ERRORCHECK);
102
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
103
pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
104
pthread_cond_init(&THR_COND_threads, NULL);
66
105
if (my_thread_init())
68
107
my_thread_global_end(); /* Clean up */
75
114
void my_thread_global_end(void)
116
struct timespec abstime;
117
bool all_threads_killed= 1;
119
set_timespec(abstime, my_thread_end_wait_time);
120
pthread_mutex_lock(&THR_LOCK_threads);
121
while (THR_thread_count > 0)
123
int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
125
if (error == ETIMEDOUT || error == ETIME)
128
We shouldn't give an error here, because if we don't have
129
pthread_kill(), programs like mysqld can't ensure that all threads
130
are killed when we enter here.
132
if (THR_thread_count)
134
"Error in my_thread_global_end(): %d threads didn't exit\n",
136
all_threads_killed= 0;
140
pthread_mutex_unlock(&THR_LOCK_threads);
142
pthread_key_delete(THR_KEY_mysys);
143
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
144
pthread_mutexattr_destroy(&my_fast_mutexattr);
146
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
147
pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
149
pthread_mutex_destroy(&THR_LOCK_lock);
150
if (all_threads_killed)
152
pthread_mutex_destroy(&THR_LOCK_threads);
153
pthread_cond_destroy(&THR_COND_threads);
79
static uint64_t thread_id= 0;
157
static my_thread_id thread_id= 0;
82
160
Allocate thread specific memory for the thread, used by mysys
92
170
bool my_thread_init(void)
94
// We should mever see my_thread_init() called twice
95
if (THR_KEY_mysys.get())
98
st_my_thread_var *tmp= new st_my_thread_var;
173
st_my_thread_var *tmp= NULL;
175
#ifdef EXTRA_DEBUG_THREADS
176
fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
177
(uint32_t) pthread_self());
180
if (pthread_getspecific(THR_KEY_mysys))
182
#ifdef EXTRA_DEBUG_THREADS
183
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
184
(long) pthread_self());
188
tmp= static_cast<st_my_thread_var *>(calloc(1, sizeof(*tmp)));
103
THR_KEY_mysys.reset(tmp);
194
pthread_setspecific(THR_KEY_mysys,tmp);
195
tmp->pthread_self= pthread_self();
196
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
197
pthread_cond_init(&tmp->suspend, NULL);
105
boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
200
pthread_mutex_lock(&THR_LOCK_threads);
106
201
tmp->id= ++thread_id;
203
pthread_mutex_unlock(&THR_LOCK_threads);
119
217
This may be called multiple times for a thread.
120
This happens for example when one calls 'server_init()'
121
server_end() and then ends with a end().
218
This happens for example when one calls 'mysql_server_init()'
219
mysql_server_end() and then ends with a mysql_end().
124
222
void my_thread_end(void)
224
st_my_thread_var *tmp=
225
static_cast<st_my_thread_var *>(pthread_getspecific(THR_KEY_mysys));
227
#ifdef EXTRA_DEBUG_THREADS
228
fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
229
(long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
231
if (tmp && tmp->init)
233
#if !defined(__bsdi__) && !defined(__OpenBSD__)
234
/* bsdi and openbsd 3.5 dumps core here */
235
pthread_cond_destroy(&tmp->suspend);
237
pthread_mutex_destroy(&tmp->mutex);
241
Decrement counter for number of running threads. We are using this
242
in my_thread_global_end() to wait until all threads have called
243
my_thread_end and thus freed all memory they have allocated in
246
pthread_mutex_lock(&THR_LOCK_threads);
247
assert(THR_thread_count != 0);
248
if (--THR_thread_count == 0)
249
pthread_cond_signal(&THR_COND_threads);
250
pthread_mutex_unlock(&THR_LOCK_threads);
128
254
struct st_my_thread_var *_my_thread_var(void)
130
return THR_KEY_mysys.get();
133
} /* namespace internal */
134
} /* namespace drizzled */
256
struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
261
/****************************************************************************
262
Get name of current thread.
263
****************************************************************************/
265
my_thread_id my_thread_dbug_id()
267
return my_thread_var->id;
270
static uint32_t get_thread_lib(void)
272
#ifdef _CS_GNU_LIBPTHREAD_VERSION
275
confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
277
if (!strncasecmp(buff, "NPTL", 4))
279
if (!strncasecmp(buff, "linuxthreads", 12))
282
return THD_LIB_OTHER;