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_open;
43
pthread_mutex_t THR_LOCK_lock;
44
pthread_mutex_t THR_LOCK_threads;
45
pthread_cond_t THR_COND_threads;
46
uint32_t THR_thread_count= 0;
47
uint32_t my_thread_end_wait_time= 5;
48
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
49
pthread_mutexattr_t my_fast_mutexattr;
51
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
52
pthread_mutexattr_t my_errorcheck_mutexattr;
55
#ifdef TARGET_OS_LINUX
58
Dummy thread spawned in my_thread_global_init() below to avoid
59
race conditions in NPTL pthread_exit code.
64
nptl_pthread_exit_hack_handler(void *arg __attribute((unused)))
71
#endif /* TARGET_OS_LINUX */
74
static uint32_t get_thread_lib(void);
54
77
initialize thread environment
64
87
bool my_thread_global_init(void)
90
thd_lib_detected= get_thread_lib();
92
if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
94
fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
98
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
100
Set mutex type to "fast" a.k.a "adaptive"
102
In this case the thread may steal the mutex from some other thread
103
that is waiting for the same mutex. This will save us some
104
context switches but may cause a thread to 'starve forever' while
105
waiting for the mutex (not likely if the code within the mutex is
108
pthread_mutexattr_init(&my_fast_mutexattr);
109
pthread_mutexattr_settype(&my_fast_mutexattr,
110
PTHREAD_MUTEX_ADAPTIVE_NP);
112
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
114
Set mutex type to "errorcheck"
116
pthread_mutexattr_init(&my_errorcheck_mutexattr);
117
pthread_mutexattr_settype(&my_errorcheck_mutexattr,
118
PTHREAD_MUTEX_ERRORCHECK);
121
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
122
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
123
pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
124
pthread_cond_init(&THR_COND_threads, NULL);
66
125
if (my_thread_init())
68
127
my_thread_global_end(); /* Clean up */
75
134
void my_thread_global_end(void)
136
struct timespec abstime;
137
bool all_threads_killed= 1;
139
set_timespec(abstime, my_thread_end_wait_time);
140
pthread_mutex_lock(&THR_LOCK_threads);
141
while (THR_thread_count > 0)
143
int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
145
if (error == ETIMEDOUT || error == ETIME)
148
We shouldn't give an error here, because if we don't have
149
pthread_kill(), programs like mysqld can't ensure that all threads
150
are killed when we enter here.
152
if (THR_thread_count)
154
"Error in my_thread_global_end(): %d threads didn't exit\n",
156
all_threads_killed= 0;
160
pthread_mutex_unlock(&THR_LOCK_threads);
162
pthread_key_delete(THR_KEY_mysys);
163
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
164
pthread_mutexattr_destroy(&my_fast_mutexattr);
166
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
167
pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
169
pthread_mutex_destroy(&THR_LOCK_open);
170
pthread_mutex_destroy(&THR_LOCK_lock);
171
if (all_threads_killed)
173
pthread_mutex_destroy(&THR_LOCK_threads);
174
pthread_cond_destroy(&THR_COND_threads);
79
static uint64_t thread_id= 0;
178
static my_thread_id thread_id= 0;
82
181
Allocate thread specific memory for the thread, used by mysys
92
191
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;
103
THR_KEY_mysys.reset(tmp);
105
boost::mutex::scoped_lock scopedLock(THR_LOCK_threads);
193
struct st_my_thread_var *tmp;
196
#ifdef EXTRA_DEBUG_THREADS
197
fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
198
(uint32_t) pthread_self());
201
if (pthread_getspecific(THR_KEY_mysys))
203
#ifdef EXTRA_DEBUG_THREADS
204
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
205
(long) pthread_self());
209
if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
214
pthread_setspecific(THR_KEY_mysys,tmp);
215
tmp->pthread_self= pthread_self();
216
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
217
pthread_cond_init(&tmp->suspend, NULL);
220
pthread_mutex_lock(&THR_LOCK_threads);
106
221
tmp->id= ++thread_id;
223
pthread_mutex_unlock(&THR_LOCK_threads);
119
237
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().
238
This happens for example when one calls 'mysql_server_init()'
239
mysql_server_end() and then ends with a mysql_end().
124
242
void my_thread_end(void)
244
struct st_my_thread_var *tmp;
245
tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
247
#ifdef EXTRA_DEBUG_THREADS
248
fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
249
(long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
251
if (tmp && tmp->init)
253
#if !defined(__bsdi__) && !defined(__OpenBSD__)
254
/* bsdi and openbsd 3.5 dumps core here */
255
pthread_cond_destroy(&tmp->suspend);
257
pthread_mutex_destroy(&tmp->mutex);
261
Decrement counter for number of running threads. We are using this
262
in my_thread_global_end() to wait until all threads have called
263
my_thread_end and thus freed all memory they have allocated in
266
pthread_mutex_lock(&THR_LOCK_threads);
267
assert(THR_thread_count != 0);
268
if (--THR_thread_count == 0)
269
pthread_cond_signal(&THR_COND_threads);
270
pthread_mutex_unlock(&THR_LOCK_threads);
128
274
struct st_my_thread_var *_my_thread_var(void)
130
return THR_KEY_mysys.get();
133
} /* namespace internal */
134
} /* namespace drizzled */
276
struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
281
/****************************************************************************
282
Get name of current thread.
283
****************************************************************************/
285
my_thread_id my_thread_dbug_id()
287
return my_thread_var->id;
290
static uint32_t get_thread_lib(void)
292
#ifdef _CS_GNU_LIBPTHREAD_VERSION
295
confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
297
if (!strncasecmp(buff, "NPTL", 4))
299
if (!strncasecmp(buff, "linuxthreads", 12))
302
return THD_LIB_OTHER;