73
73
#include "mysys_priv.h"
75
75
#include "thr_lock.h"
76
#include <mystrings/m_string.h>
79
79
bool thr_lock_inited=0;
80
uint32_t locks_immediate = 0L, locks_waited = 0L;
80
ulong locks_immediate = 0L, locks_waited = 0L;
81
81
ulong table_lock_wait_timeout;
82
82
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
113
113
#ifdef EXTRA_DEBUG
114
114
#define MAX_FOUND_ERRORS 10 /* Report 10 first errors */
115
static uint32_t found_errors=0;
115
static uint found_errors=0;
117
117
static int check_lock(struct st_lock_list *list, const char* lock_type,
118
118
const char *where, bool same_owner, bool no_cond)
120
120
THR_LOCK_DATA *data,**prev;
122
122
THR_LOCK_OWNER *first_owner;
124
124
prev= &list->data;
177
177
static void check_locks(THR_LOCK *lock, const char *where,
178
178
bool allow_no_locks)
180
uint32_t old_found_errors=found_errors;
180
uint old_found_errors=found_errors;
182
182
if (found_errors < MAX_FOUND_ERRORS)
300
300
void thr_lock_init(THR_LOCK *lock)
302
memset(lock, 0, sizeof(*lock));
303
pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST);
302
bzero((char*) lock,sizeof(*lock));
303
VOID(pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST));
304
304
lock->read.last= &lock->read.data;
305
305
lock->read_wait.last= &lock->read_wait.data;
306
306
lock->write_wait.last= &lock->write_wait.data;
317
317
void thr_lock_delete(THR_LOCK *lock)
319
pthread_mutex_destroy(&lock->mutex);
319
VOID(pthread_mutex_destroy(&lock->mutex));
320
320
pthread_mutex_lock(&THR_LOCK_lock);
321
321
thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
322
322
pthread_mutex_unlock(&THR_LOCK_lock);
475
475
data->cond=0; /* safety */
476
476
data->type=lock_type;
477
477
data->owner= owner; /* Must be reset ! */
478
pthread_mutex_lock(&lock->mutex);
478
VOID(pthread_mutex_lock(&lock->mutex));
479
479
check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
480
480
"enter read_lock" : "enter write_lock",0);
481
481
if ((int) lock_type <= (int) TL_READ_NO_INSERT)
706
706
lock->read_no_write_count++;
708
708
data->cond=0; /* Mark thread free */
709
pthread_cond_signal(cond);
709
VOID(pthread_cond_signal(cond));
710
710
} while ((data=data->next));
711
711
*lock->read_wait.last=0;
712
712
if (!lock->read_wait.data)
807
807
pthread_cond_t *cond=data->cond;
808
808
data->cond=0; /* Mark thread free */
809
pthread_cond_signal(cond); /* Start waiting thread */
809
VOID(pthread_cond_signal(cond)); /* Start waiting thread */
811
811
if (data->type != TL_WRITE_ALLOW_WRITE ||
812
812
!lock->write_wait.data ||
853
853
lock->write.last= &data->next;
854
854
data->next=0; /* Only one write lock */
855
855
data->cond=0; /* Mark thread free */
856
pthread_cond_signal(cond); /* Start waiting thread */
856
VOID(pthread_cond_signal(cond)); /* Start waiting thread */
857
857
} while (lock_type == TL_WRITE_ALLOW_WRITE &&
858
858
(data=lock->write_wait.data) &&
859
859
data->type == TL_WRITE_ALLOW_WRITE);
881
#define LOCK_CMP(A,B) ((unsigned char*) (A->lock) - (uint) ((A)->type) < (unsigned char*) (B->lock)- (uint) ((B)->type))
881
#define LOCK_CMP(A,B) ((uchar*) (A->lock) - (uint) ((A)->type) < (uchar*) (B->lock)- (uint) ((B)->type))
883
static void sort_locks(THR_LOCK_DATA **data,uint32_t count)
883
static void sort_locks(THR_LOCK_DATA **data,uint count)
885
885
THR_LOCK_DATA **pos,**end,**prev,*tmp;
904
904
enum enum_thr_lock_result
905
thr_multi_lock(THR_LOCK_DATA **data, uint32_t count, THR_LOCK_OWNER *owner)
905
thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
907
907
THR_LOCK_DATA **pos,**end;
974
974
/* free all locks */
976
void thr_multi_unlock(THR_LOCK_DATA **data,uint32_t count)
976
void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
978
978
THR_LOCK_DATA **pos,**end;
1201
1201
#include <my_sys.h>
1203
static void thr_print_lock(const char* name,struct st_lock_list *list)
1205
THR_LOCK_DATA *data,**prev;
1210
printf("%-10s: ",name);
1212
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
1214
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
1216
if (data->prev != prev)
1217
printf("\nWarning: prev didn't point at previous lock\n");
1221
if (prev != list->last)
1222
printf("Warning: last didn't point at last lock\n");
1226
void thr_print_locks(void)
1231
pthread_mutex_lock(&THR_LOCK_lock);
1232
puts("Current locks:");
1233
for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
1234
list= list_rest(list))
1236
THR_LOCK *lock=(THR_LOCK*) list->data;
1237
VOID(pthread_mutex_lock(&lock->mutex));
1238
printf("lock: 0x%lx:",(ulong) lock);
1239
if ((lock->write_wait.data || lock->read_wait.data) &&
1240
(! lock->read.data && ! lock->write.data))
1241
printf(" WARNING: ");
1242
if (lock->write.data)
1244
if (lock->write_wait.data)
1245
printf(" write_wait");
1246
if (lock->read.data)
1248
if (lock->read_wait.data)
1249
printf(" read_wait");
1251
thr_print_lock("write",&lock->write);
1252
thr_print_lock("write_wait",&lock->write_wait);
1253
thr_print_lock("read",&lock->read);
1254
thr_print_lock("read_wait",&lock->read_wait);
1255
VOID(pthread_mutex_unlock(&lock->mutex));
1259
pthread_mutex_unlock(&THR_LOCK_lock);
1203
1262
/*****************************************************************************
1204
1263
** Test of thread locks
1205
1264
****************************************************************************/
1329
1388
thr_print_locks();
1330
1389
pthread_mutex_lock(&LOCK_thread_count);
1331
1390
thread_count--;
1332
pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
1391
VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
1333
1392
pthread_mutex_unlock(&LOCK_thread_count);
1334
free((unsigned char*) arg);