~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Functions to handle initializating and allocationg of all mysys & debug
18
  thread variables.
19
*/
20
994.2.4 by Monty Taylor
Blast. Fixed some make distcheck issues.
21
#include "mysys/mysys_priv.h"
575.3.1 by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found.
22
#include <mysys/my_pthread.h>
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
23
#include <mystrings/m_string.h>
612.2.6 by Monty Taylor
OpenSolaris builds.
24
25
#include <stdio.h>
1 by brian
clean slate
26
#include <signal.h>
27
481.1.15 by Monty Taylor
Removed time.h and sys/time.h from global.h.
28
#if TIME_WITH_SYS_TIME
29
# include <sys/time.h>
30
# include <time.h>
31
#else
32
# if HAVE_SYS_TIME_H
33
#  include <sys/time.h>
34
# else
35
#  include <time.h>
36
# endif
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
37
#endif
481.1.15 by Monty Taylor
Removed time.h and sys/time.h from global.h.
38
482 by Brian Aker
Remove uint.
39
uint32_t thd_lib_detected= 0;
8 by Brian Aker
Pstack removal. Cleanup around final my_pthread.c removal.
40
860 by Brian Aker
Remove USE_TLS (dead define)
41
pthread_key_t THR_KEY_mysys;
596 by Brian Aker
Refactor out dead mutexes
42
pthread_mutex_t THR_LOCK_lock;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
43
pthread_mutex_t THR_LOCK_threads;
1 by brian
clean slate
44
pthread_cond_t  THR_COND_threads;
482 by Brian Aker
Remove uint.
45
uint32_t            THR_thread_count= 0;
46
uint32_t 		my_thread_end_wait_time= 5;
1 by brian
clean slate
47
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
48
pthread_mutexattr_t my_fast_mutexattr;
49
#endif
50
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
51
pthread_mutexattr_t my_errorcheck_mutexattr;
52
#endif
53
54
482 by Brian Aker
Remove uint.
55
static uint32_t get_thread_lib(void);
1 by brian
clean slate
56
57
/*
58
  initialize thread environment
59
60
  SYNOPSIS
61
    my_thread_global_init()
62
63
  RETURN
64
    0  ok
65
    1  error (Couldn't create THR_KEY_mysys)
66
*/
67
146 by Brian Aker
my_bool cleanup.
68
bool my_thread_global_init(void)
1 by brian
clean slate
69
{
70
  int pth_ret;
71
  thd_lib_detected= get_thread_lib();
72
73
  if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0)
74
  {
75
    fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret);
76
    return 1;
77
  }
78
79
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
80
  /*
81
    Set mutex type to "fast" a.k.a "adaptive"
82
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
87
    short).
88
  */
89
  pthread_mutexattr_init(&my_fast_mutexattr);
90
  pthread_mutexattr_settype(&my_fast_mutexattr,
91
                            PTHREAD_MUTEX_ADAPTIVE_NP);
92
#endif
93
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
94
  /*
95
    Set mutex type to "errorcheck"
96
  */
97
  pthread_mutexattr_init(&my_errorcheck_mutexattr);
98
  pthread_mutexattr_settype(&my_errorcheck_mutexattr,
99
                            PTHREAD_MUTEX_ERRORCHECK);
100
#endif
101
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);
105
  if (my_thread_init())
106
  {
107
    my_thread_global_end();			/* Clean up */
108
    return 1;
109
  }
110
  return 0;
111
}
112
113
114
void my_thread_global_end(void)
115
{
116
  struct timespec abstime;
146 by Brian Aker
my_bool cleanup.
117
  bool all_threads_killed= 1;
1 by brian
clean slate
118
119
  set_timespec(abstime, my_thread_end_wait_time);
120
  pthread_mutex_lock(&THR_LOCK_threads);
121
  while (THR_thread_count > 0)
122
  {
123
    int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads,
124
                                      &abstime);
125
    if (error == ETIMEDOUT || error == ETIME)
126
    {
127
      /*
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.
131
      */
132
      if (THR_thread_count)
133
        fprintf(stderr,
134
                "Error in my_thread_global_end(): %d threads didn't exit\n",
135
                THR_thread_count);
136
      all_threads_killed= 0;
137
      break;
138
    }
139
  }
140
  pthread_mutex_unlock(&THR_LOCK_threads);
141
142
  pthread_key_delete(THR_KEY_mysys);
143
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
144
  pthread_mutexattr_destroy(&my_fast_mutexattr);
145
#endif
146
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
147
  pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
148
#endif
149
  pthread_mutex_destroy(&THR_LOCK_lock);
150
  if (all_threads_killed)
151
  {
152
    pthread_mutex_destroy(&THR_LOCK_threads);
153
    pthread_cond_destroy(&THR_COND_threads);
154
  }
155
}
156
157
static my_thread_id thread_id= 0;
158
159
/*
51.3.28 by Jay Pipes
DBUG entirely removed from server and client
160
  Allocate thread specific memory for the thread, used by mysys
1 by brian
clean slate
161
162
  SYNOPSIS
163
    my_thread_init()
164
165
  RETURN
166
    0  ok
167
    1  Fatal error; mysys/dbug functions can't be used
168
*/
169
146 by Brian Aker
my_bool cleanup.
170
bool my_thread_init(void)
1 by brian
clean slate
171
{
172
  struct st_my_thread_var *tmp;
146 by Brian Aker
my_bool cleanup.
173
  bool error=0;
1 by brian
clean slate
174
175
#ifdef EXTRA_DEBUG_THREADS
176
  fprintf(stderr,"my_thread_init(): thread_id: 0x%lx\n",
298 by Brian Aker
ulong conversion.
177
          (uint32_t) pthread_self());
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
178
#endif
1 by brian
clean slate
179
5 by Brian Aker
Removed my_pthread_setprio()
180
  if (pthread_getspecific(THR_KEY_mysys))
1 by brian
clean slate
181
  {
182
#ifdef EXTRA_DEBUG_THREADS
183
    fprintf(stderr,"my_thread_init() called more than once in thread 0x%lx\n",
184
            (long) pthread_self());
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
185
#endif
1 by brian
clean slate
186
    goto end;
187
  }
188
  if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
189
  {
190
    error= 1;
191
    goto end;
192
  }
193
  pthread_setspecific(THR_KEY_mysys,tmp);
194
  tmp->pthread_self= pthread_self();
195
  pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
196
  pthread_cond_init(&tmp->suspend, NULL);
197
  tmp->init= 1;
198
199
  pthread_mutex_lock(&THR_LOCK_threads);
200
  tmp->id= ++thread_id;
201
  ++THR_thread_count;
202
  pthread_mutex_unlock(&THR_LOCK_threads);
203
204
end:
205
  return error;
206
}
207
208
209
/*
210
  Deallocate memory used by the thread for book-keeping
211
212
  SYNOPSIS
213
    my_thread_end()
214
215
  NOTE
216
    This may be called multiple times for a thread.
217
    This happens for example when one calls 'mysql_server_init()'
218
    mysql_server_end() and then ends with a mysql_end().
219
*/
220
221
void my_thread_end(void)
222
{
223
  struct st_my_thread_var *tmp;
5 by Brian Aker
Removed my_pthread_setprio()
224
  tmp= (struct st_my_thread_var *)pthread_getspecific(THR_KEY_mysys);
1 by brian
clean slate
225
226
#ifdef EXTRA_DEBUG_THREADS
227
  fprintf(stderr,"my_thread_end(): tmp: 0x%lx  pthread_self: 0x%lx  thread_id: %ld\n",
228
	  (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
229
#endif
1 by brian
clean slate
230
  if (tmp && tmp->init)
231
  {
232
#if !defined(__bsdi__) && !defined(__OpenBSD__)
233
 /* bsdi and openbsd 3.5 dumps core here */
234
    pthread_cond_destroy(&tmp->suspend);
235
#endif
236
    pthread_mutex_destroy(&tmp->mutex);
237
    tmp->init= 0;
238
239
    /*
240
      Decrement counter for number of running threads. We are using this
241
      in my_thread_global_end() to wait until all threads have called
242
      my_thread_end and thus freed all memory they have allocated in
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
243
      my_thread_init()
1 by brian
clean slate
244
    */
245
    pthread_mutex_lock(&THR_LOCK_threads);
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
246
    assert(THR_thread_count != 0);
1 by brian
clean slate
247
    if (--THR_thread_count == 0)
248
      pthread_cond_signal(&THR_COND_threads);
249
   pthread_mutex_unlock(&THR_LOCK_threads);
250
  }
251
}
252
253
struct st_my_thread_var *_my_thread_var(void)
254
{
5 by Brian Aker
Removed my_pthread_setprio()
255
  struct st_my_thread_var *tmp= (struct st_my_thread_var*)pthread_getspecific(THR_KEY_mysys);
1 by brian
clean slate
256
  return tmp;
257
}
258
259
260
/****************************************************************************
261
  Get name of current thread.
262
****************************************************************************/
263
264
my_thread_id my_thread_dbug_id()
265
{
266
  return my_thread_var->id;
267
}
268
482 by Brian Aker
Remove uint.
269
static uint32_t get_thread_lib(void)
1 by brian
clean slate
270
{
271
#ifdef _CS_GNU_LIBPTHREAD_VERSION
272
  char buff[64];
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
273
1 by brian
clean slate
274
  confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff));
275
276
  if (!strncasecmp(buff, "NPTL", 4))
277
    return THD_LIB_NPTL;
278
  if (!strncasecmp(buff, "linuxthreads", 12))
279
    return THD_LIB_LT;
280
#endif
281
  return THD_LIB_OTHER;
282
}