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_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
187
We can't use mutex_locks here if we are using windows as
188
we may have compiled the program with SAFE_MUTEX, in which
189
case the checking of mutex_locks will not work until
190
the pthread_self thread specific variable is initialized.
89
194
1 Fatal error; mysys/dbug functions can't be used
92
197
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);
199
struct st_my_thread_var *tmp;
202
#ifdef EXTRA_DEBUG_THREADS
203
fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
204
(uint32_t) pthread_self());
207
if (pthread_getspecific(THR_KEY_mysys))
209
#ifdef EXTRA_DEBUG_THREADS
210
fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
211
(long) pthread_self());
215
if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
220
pthread_setspecific(THR_KEY_mysys,tmp);
221
tmp->pthread_self= pthread_self();
222
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
223
pthread_cond_init(&tmp->suspend, NULL);
226
pthread_mutex_lock(&THR_LOCK_threads);
106
227
tmp->id= ++thread_id;
229
pthread_mutex_unlock(&THR_LOCK_threads);
124
248
void my_thread_end(void)
250
struct st_my_thread_var *tmp;
251
tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
253
#ifdef EXTRA_DEBUG_THREADS
254
fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n",
255
(long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
257
if (tmp && tmp->init)
259
#if !defined(__bsdi__) && !defined(__OpenBSD__)
260
/* bsdi and openbsd 3.5 dumps core here */
261
pthread_cond_destroy(&tmp->suspend);
263
pthread_mutex_destroy(&tmp->mutex);
267
Decrement counter for number of running threads. We are using this
268
in my_thread_global_end() to wait until all threads have called
269
my_thread_end and thus freed all memory they have allocated in
272
pthread_mutex_lock(&THR_LOCK_threads);
273
assert(THR_thread_count != 0);
274
if (--THR_thread_count == 0)
275
pthread_cond_signal(&THR_COND_threads);
276
pthread_mutex_unlock(&THR_LOCK_threads);
128
280
struct st_my_thread_var *_my_thread_var(void)
130
return THR_KEY_mysys.get();
133
} /* namespace internal */
134
} /* namespace drizzled */
282
struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
287
/****************************************************************************
288
Get name of current thread.
289
****************************************************************************/
291
my_thread_id my_thread_dbug_id()
293
return my_thread_var->id;
296
static uint32_t get_thread_lib(void)
298
#ifdef _CS_GNU_LIBPTHREAD_VERSION
301
confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
303
if (!strncasecmp(buff, "NPTL", 4))
305
if (!strncasecmp(buff, "linuxthreads", 12))
308
return THD_LIB_OTHER;