~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/thr_lock.c

  • Committer: Monty Taylor
  • Date: 2008-10-04 03:15:20 UTC
  • mfrom: (438.4.1 drizzle-clean-code)
  • Revision ID: monty@inaugust.com-20081004031520-j3d38cge8tlrwuhh
MergedĀ fromĀ Lee.

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
 
71
71
*/
72
72
 
73
 
#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
74
 
#define FORCE_DBUG_OFF
75
 
#endif
76
 
 
77
73
#include "mysys_priv.h"
78
74
 
79
75
#include "thr_lock.h"
80
 
#include <m_string.h>
 
76
#include <mystrings/m_string.h>
81
77
#include <errno.h>
82
78
 
83
 
my_bool thr_lock_inited=0;
84
 
ulong locks_immediate = 0L, locks_waited = 0L;
 
79
bool thr_lock_inited=0;
 
80
uint32_t locks_immediate = 0L, locks_waited = 0L;
85
81
ulong table_lock_wait_timeout;
86
82
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
87
83
 
102
98
** For the future (now the thread specific cond is alloced by my_pthread.c)
103
99
*/
104
100
 
105
 
my_bool init_thr_lock()
 
101
bool init_thr_lock()
106
102
{
107
103
  thr_lock_inited=1;
108
104
  return 0;
109
105
}
110
106
 
111
 
static inline my_bool
 
107
static inline bool
112
108
thr_lock_owner_equal(THR_LOCK_OWNER *rhs, THR_LOCK_OWNER *lhs)
113
109
{
114
110
  return rhs == lhs;
115
111
}
116
112
 
117
 
 
118
113
#ifdef EXTRA_DEBUG
119
114
#define MAX_FOUND_ERRORS        10              /* Report 10 first errors */
120
115
static uint found_errors=0;
121
116
 
122
117
static int check_lock(struct st_lock_list *list, const char* lock_type,
123
 
                      const char *where, my_bool same_owner, my_bool no_cond)
 
118
                      const char *where, bool same_owner, bool no_cond)
124
119
{
125
120
  THR_LOCK_DATA *data,**prev;
126
121
  uint count=0;
180
175
 
181
176
 
182
177
static void check_locks(THR_LOCK *lock, const char *where,
183
 
                        my_bool allow_no_locks)
 
178
                        bool allow_no_locks)
184
179
{
185
180
  uint old_found_errors=found_errors;
186
 
  DBUG_ENTER("check_locks");
187
181
 
188
182
  if (found_errors < MAX_FOUND_ERRORS)
189
183
  {
202
196
        if ((int) data->type == (int) TL_READ_NO_INSERT)
203
197
          count++;
204
198
        /* Protect against infinite loop. */
205
 
        DBUG_ASSERT(count <= lock->read_no_write_count);
 
199
        assert(count <= lock->read_no_write_count);
206
200
      }
207
201
      if (count != lock->read_no_write_count)
208
202
      {
275
269
            fprintf(stderr,
276
270
                    "Warning at '%s': Found lock of type %d that is write and read locked\n",
277
271
                    where, lock->write.data->type);
278
 
            DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n",
279
 
                    where, lock->write.data->type));
280
 
 
281
272
          }
282
273
        }
283
274
        if (lock->read_wait.data)
295
286
        }
296
287
      }
297
288
    }
298
 
    if (found_errors != old_found_errors)
299
 
    {
300
 
      DBUG_PRINT("error",("Found wrong lock"));
301
 
    }
302
289
  }
303
 
  DBUG_VOID_RETURN;
 
290
  return;
304
291
}
305
292
 
306
293
#else /* EXTRA_DEBUG */
312
299
 
313
300
void thr_lock_init(THR_LOCK *lock)
314
301
{
315
 
  DBUG_ENTER("thr_lock_init");
316
 
  bzero((char*) lock,sizeof(*lock));
317
 
  VOID(pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST));
 
302
  memset(lock, 0, sizeof(*lock));
 
303
  pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST);
318
304
  lock->read.last= &lock->read.data;
319
305
  lock->read_wait.last= &lock->read_wait.data;
320
306
  lock->write_wait.last= &lock->write_wait.data;
324
310
  lock->list.data=(void*) lock;
325
311
  thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list);
326
312
  pthread_mutex_unlock(&THR_LOCK_lock);
327
 
  DBUG_VOID_RETURN;
 
313
  return;
328
314
}
329
315
 
330
316
 
331
317
void thr_lock_delete(THR_LOCK *lock)
332
318
{
333
 
  DBUG_ENTER("thr_lock_delete");
334
 
  VOID(pthread_mutex_destroy(&lock->mutex));
 
319
  pthread_mutex_destroy(&lock->mutex);
335
320
  pthread_mutex_lock(&THR_LOCK_lock);
336
321
  thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
337
322
  pthread_mutex_unlock(&THR_LOCK_lock);
338
 
  DBUG_VOID_RETURN;
 
323
  return;
339
324
}
340
325
 
341
326
 
359
344
}
360
345
 
361
346
 
362
 
static inline my_bool
 
347
static inline bool
363
348
have_old_read_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
364
349
{
365
350
  for ( ; data ; data=data->next)
370
355
  return 0;
371
356
}
372
357
 
373
 
static inline my_bool have_specific_lock(THR_LOCK_DATA *data,
 
358
static inline bool have_specific_lock(THR_LOCK_DATA *data,
374
359
                                         enum thr_lock_type type)
375
360
{
376
361
  for ( ; data ; data=data->next)
387
372
 
388
373
static enum enum_thr_lock_result
389
374
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
390
 
              my_bool in_wait_list)
 
375
              bool in_wait_list)
391
376
{
392
377
  struct st_my_thread_var *thread_var= my_thread_var;
393
378
  pthread_cond_t *cond= &thread_var->suspend;
394
379
  struct timespec wait_timeout;
395
380
  enum enum_thr_lock_result result= THR_LOCK_ABORTED;
396
 
  my_bool can_deadlock= test(data->owner->info->n_cursors);
397
 
  DBUG_ENTER("wait_for_lock");
 
381
  bool can_deadlock= test(data->owner->info->n_cursors);
398
382
 
399
383
  if (!in_wait_list)
400
384
  {
433
417
    */
434
418
    if (data->cond == 0)
435
419
    {
436
 
      DBUG_PRINT("thr_lock", ("lock granted/aborted"));
437
420
      break;
438
421
    }
439
422
    if (rc == ETIMEDOUT || rc == ETIME)
440
423
    {
441
424
      /* purecov: begin inspected */
442
 
      DBUG_PRINT("thr_lock", ("lock timed out"));
443
425
      result= THR_LOCK_WAIT_TIMEOUT;
444
426
      break;
445
427
      /* purecov: end */
446
428
    }
447
429
  }
448
 
  DBUG_PRINT("thr_lock", ("aborted: %d  in_wait_list: %d",
449
 
                          thread_var->abort, in_wait_list));
450
 
 
451
430
  if (data->cond || data->type == TL_UNLOCK)
452
431
  {
453
432
    if (data->cond)                             /* aborted or timed out */
462
441
    }
463
442
    else
464
443
    {
465
 
      DBUG_PRINT("thr_lock", ("lock aborted"));
466
444
      check_locks(data->lock, "aborted wait_for_lock", 0);
467
445
    }
468
446
  }
480
458
  thread_var->current_mutex= 0;
481
459
  thread_var->current_cond=  0;
482
460
  pthread_mutex_unlock(&thread_var->mutex);
483
 
  DBUG_RETURN(result);
 
461
  return(result);
484
462
}
485
463
 
486
464
 
492
470
  enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
493
471
  struct st_lock_list *wait_queue;
494
472
  THR_LOCK_DATA *lock_owner;
495
 
  DBUG_ENTER("thr_lock");
496
473
 
497
474
  data->next=0;
498
475
  data->cond=0;                                 /* safety */
499
476
  data->type=lock_type;
500
477
  data->owner= owner;                           /* Must be reset ! */
501
 
  VOID(pthread_mutex_lock(&lock->mutex));
502
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx  type: %d",
503
 
                     (long) data, data->owner->info->thread_id,
504
 
                     (long) lock, (int) lock_type));
 
478
  pthread_mutex_lock(&lock->mutex);
505
479
  check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
506
480
              "enter read_lock" : "enter write_lock",0);
507
481
  if ((int) lock_type <= (int) TL_READ_NO_INSERT)
518
492
           and the read lock is not TL_READ_NO_INSERT
519
493
      */
520
494
 
521
 
      DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
522
 
                         lock->write.data->owner->info->thread_id));
523
495
      if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
524
496
          (lock->write.data->type <= TL_WRITE_DELAYED &&
525
497
           (((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
631
603
          We have already got a write lock or all locks are
632
604
          TL_WRITE_ALLOW_WRITE
633
605
        */
634
 
        DBUG_PRINT("info", ("write_wait.data: 0x%lx  old_type: %d",
635
 
                            (ulong) lock->write_wait.data,
636
 
                            lock->write.data->type));
637
606
 
638
607
        (*lock->write.last)=data;       /* Add to running fifo */
639
608
        data->prev=lock->write.last;
644
613
        statistic_increment(locks_immediate,&THR_LOCK_lock);
645
614
        goto end;
646
615
      }
647
 
      DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
648
 
                         lock->write.data->owner->info->thread_id));
649
616
    }
650
617
    else
651
618
    {
652
 
      DBUG_PRINT("info", ("write_wait.data: 0x%lx",
653
 
                          (ulong) lock->write_wait.data));
654
619
      if (!lock->write_wait.data)
655
620
      {                                         /* no scheduled write locks */
656
 
        my_bool concurrent_insert= 0;
 
621
        bool concurrent_insert= 0;
657
622
        if (lock_type == TL_WRITE_CONCURRENT_INSERT)
658
623
        {
659
624
          concurrent_insert= 1;
680
645
          goto end;
681
646
        }
682
647
      }
683
 
      DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx  type: %d",
684
 
                         lock->read.data->owner->info->thread_id, data->type));
685
648
    }
686
649
    wait_queue= &lock->write_wait;
687
650
  }
694
657
  lock_owner= lock->read.data ? lock->read.data : lock->write.data;
695
658
  if (lock_owner && lock_owner->owner->info == owner->info)
696
659
  {
697
 
    DBUG_PRINT("lock",("deadlock"));
698
660
    result= THR_LOCK_DEADLOCK;
699
661
    goto end;
700
662
  }
701
663
  /* Can't get lock yet;  Wait for it */
702
 
  DBUG_RETURN(wait_for_lock(wait_queue, data, 0));
 
664
  return(wait_for_lock(wait_queue, data, 0));
703
665
end:
704
666
  pthread_mutex_unlock(&lock->mutex);
705
 
  DBUG_RETURN(result);
 
667
  return(result);
706
668
}
707
669
 
708
670
 
709
671
static inline void free_all_read_locks(THR_LOCK *lock,
710
 
                                       my_bool using_concurrent_insert)
 
672
                                       bool using_concurrent_insert)
711
673
{
712
674
  THR_LOCK_DATA *data=lock->read_wait.data;
713
675
 
743
705
      }
744
706
      lock->read_no_write_count++;
745
707
    }      
746
 
    /* purecov: begin inspected */
747
 
    DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
748
 
                       data->owner->info->thread_id));
749
 
    /* purecov: end */
750
708
    data->cond=0;                               /* Mark thread free */
751
 
    VOID(pthread_cond_signal(cond));
 
709
    pthread_cond_signal(cond);
752
710
  } while ((data=data->next));
753
711
  *lock->read_wait.last=0;
754
712
  if (!lock->read_wait.data)
762
720
{
763
721
  THR_LOCK *lock=data->lock;
764
722
  enum thr_lock_type lock_type=data->type;
765
 
  DBUG_ENTER("thr_unlock");
766
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
767
 
                     (long) data, data->owner->info->thread_id, (long) lock));
768
723
  pthread_mutex_lock(&lock->mutex);
769
724
  check_locks(lock,"start of release lock",0);
770
725
 
798
753
  check_locks(lock,"after releasing lock",1);
799
754
  wake_up_waiters(lock);
800
755
  pthread_mutex_unlock(&lock->mutex);
801
 
  DBUG_VOID_RETURN;
 
756
  return;
802
757
}
803
758
 
804
759
 
815
770
  THR_LOCK_DATA *data;
816
771
  enum thr_lock_type lock_type;
817
772
 
818
 
  DBUG_ENTER("wake_up_waiters");
819
 
 
820
773
  if (!lock->write.data)                        /* If no active write locks */
821
774
  {
822
775
    data=lock->write_wait.data;
833
786
          lock->write_lock_count=0;
834
787
          if (lock->read_wait.data)
835
788
          {
836
 
            DBUG_PRINT("info",("Freeing all read_locks because of max_write_lock_count"));
837
789
            free_all_read_locks(lock,0);
838
790
            goto end;
839
791
          }
851
803
          if (data->type == TL_WRITE_CONCURRENT_INSERT &&
852
804
              (*lock->check_status)(data->status_param))
853
805
            data->type=TL_WRITE;                        /* Upgrade lock */
854
 
          /* purecov: begin inspected */
855
 
          DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
856
 
                             data->type, data->owner->info->thread_id));
857
 
          /* purecov: end */
858
806
          {
859
807
            pthread_cond_t *cond=data->cond;
860
808
            data->cond=0;                               /* Mark thread free */
861
 
            VOID(pthread_cond_signal(cond));    /* Start waiting thread */
 
809
            pthread_cond_signal(cond);  /* Start waiting thread */
862
810
          }
863
811
          if (data->type != TL_WRITE_ALLOW_WRITE ||
864
812
              !lock->write_wait.data ||
875
823
                            data &&
876
824
                            (data->type == TL_WRITE_CONCURRENT_INSERT ||
877
825
                             data->type == TL_WRITE_ALLOW_WRITE));
878
 
      else
879
 
      {
880
 
        DBUG_PRINT("lock",("No waiting read locks to free"));
881
 
      }
882
826
    }
883
827
    else if (data &&
884
828
             (lock_type=data->type) <= TL_WRITE_DELAYED &&
909
853
        lock->write.last= &data->next;
910
854
        data->next=0;                           /* Only one write lock */
911
855
        data->cond=0;                           /* Mark thread free */
912
 
        VOID(pthread_cond_signal(cond));        /* Start waiting thread */
 
856
        pthread_cond_signal(cond);      /* Start waiting thread */
913
857
      } while (lock_type == TL_WRITE_ALLOW_WRITE &&
914
858
               (data=lock->write_wait.data) &&
915
859
               data->type == TL_WRITE_ALLOW_WRITE);
923
867
  }
924
868
end:
925
869
  check_locks(lock, "after waking up waiters", 0);
926
 
  DBUG_VOID_RETURN;
 
870
  return;
927
871
}
928
872
 
929
873
 
961
905
thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
962
906
{
963
907
  THR_LOCK_DATA **pos,**end;
964
 
  DBUG_ENTER("thr_multi_lock");
965
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
966
908
  if (count > 1)
967
909
    sort_locks(data,count);
968
910
  /* lock everything */
972
914
    if (result != THR_LOCK_SUCCESS)
973
915
    {                                           /* Aborted */
974
916
      thr_multi_unlock(data,(uint) (pos-data));
975
 
      DBUG_RETURN(result);
 
917
      return(result);
976
918
    }
977
919
#ifdef MAIN
978
920
    printf("Thread: %s  Got lock: 0x%lx  type: %d\n",my_thread_name(),
1026
968
    } while (pos != data);
1027
969
  }
1028
970
#endif
1029
 
  DBUG_RETURN(THR_LOCK_SUCCESS);
 
971
  return(THR_LOCK_SUCCESS);
1030
972
}
1031
973
 
1032
974
  /* free all locks */
1034
976
void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
1035
977
{
1036
978
  THR_LOCK_DATA **pos,**end;
1037
 
  DBUG_ENTER("thr_multi_unlock");
1038
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
1039
979
 
1040
980
  for (pos=data,end=data+count; pos < end ; pos++)
1041
981
  {
1046
986
#endif
1047
987
    if ((*pos)->type != TL_UNLOCK)
1048
988
      thr_unlock(*pos);
1049
 
    else
1050
 
    {
1051
 
      DBUG_PRINT("lock",("Free lock: data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
1052
 
                         (long) *pos, (*pos)->owner->info->thread_id,
1053
 
                         (long) (*pos)->lock));
1054
 
    }
1055
989
  }
1056
 
  DBUG_VOID_RETURN;
 
990
  return;
1057
991
}
1058
992
 
1059
993
/*
1061
995
  TL_WRITE_ONLY to abort any new accesses to the lock
1062
996
*/
1063
997
 
1064
 
void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock)
 
998
void thr_abort_locks(THR_LOCK *lock, bool upgrade_lock)
1065
999
{
1066
1000
  THR_LOCK_DATA *data;
1067
 
  DBUG_ENTER("thr_abort_locks");
1068
1001
  pthread_mutex_lock(&lock->mutex);
1069
1002
 
1070
1003
  for (data=lock->read_wait.data; data ; data=data->next)
1086
1019
  if (upgrade_lock && lock->write.data)
1087
1020
    lock->write.data->type=TL_WRITE_ONLY;
1088
1021
  pthread_mutex_unlock(&lock->mutex);
1089
 
  DBUG_VOID_RETURN;
 
1022
  return;
1090
1023
}
1091
1024
 
1092
1025
 
1096
1029
  This is used to abort all locks for a specific thread
1097
1030
*/
1098
1031
 
1099
 
my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
 
1032
bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
1100
1033
{
1101
1034
  THR_LOCK_DATA *data;
1102
 
  my_bool found= FALSE;
1103
 
  DBUG_ENTER("thr_abort_locks_for_thread");
 
1035
  bool found= false;
1104
1036
 
1105
1037
  pthread_mutex_lock(&lock->mutex);
1106
1038
  for (data= lock->read_wait.data; data ; data= data->next)
1107
1039
  {
1108
1040
    if (data->owner->info->thread_id == thread_id)    /* purecov: tested */
1109
1041
    {
1110
 
      DBUG_PRINT("info",("Aborting read-wait lock"));
1111
1042
      data->type= TL_UNLOCK;                    /* Mark killed */
1112
1043
      /* It's safe to signal the cond first: we're still holding the mutex. */
1113
 
      found= TRUE;
 
1044
      found= true;
1114
1045
      pthread_cond_signal(data->cond);
1115
1046
      data->cond= 0;                            /* Removed from list */
1116
1047
 
1124
1055
  {
1125
1056
    if (data->owner->info->thread_id == thread_id) /* purecov: tested */
1126
1057
    {
1127
 
      DBUG_PRINT("info",("Aborting write-wait lock"));
1128
1058
      data->type= TL_UNLOCK;
1129
 
      found= TRUE;
 
1059
      found= true;
1130
1060
      pthread_cond_signal(data->cond);
1131
1061
      data->cond= 0;
1132
1062
 
1138
1068
  }
1139
1069
  wake_up_waiters(lock);
1140
1070
  pthread_mutex_unlock(&lock->mutex);
1141
 
  DBUG_RETURN(found);
 
1071
  return(found);
1142
1072
}
1143
1073
 
1144
1074
 
1176
1106
                              enum thr_lock_type new_lock_type)
1177
1107
{
1178
1108
  THR_LOCK *lock=in_data->lock;
1179
 
#ifndef DBUG_OFF
1180
 
  enum thr_lock_type old_lock_type= in_data->type;
1181
 
#endif
1182
 
  DBUG_ENTER("thr_downgrade_write_only_lock");
1183
1109
 
1184
1110
  pthread_mutex_lock(&lock->mutex);
1185
 
  DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
1186
 
  DBUG_ASSERT(old_lock_type > new_lock_type);
1187
1111
  in_data->type= new_lock_type;
1188
1112
  check_locks(lock,"after downgrading lock",0);
1189
1113
 
1190
1114
  pthread_mutex_unlock(&lock->mutex);
1191
 
  DBUG_VOID_RETURN;
 
1115
  return;
1192
1116
}
1193
1117
 
1194
1118
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
1195
1119
 
1196
 
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
 
1120
bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1197
1121
{
1198
1122
  THR_LOCK *lock=data->lock;
1199
 
  DBUG_ENTER("thr_upgrade_write_delay_lock");
1200
1123
 
1201
1124
  pthread_mutex_lock(&lock->mutex);
1202
1125
  if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
1203
1126
  {
1204
1127
    pthread_mutex_unlock(&lock->mutex);
1205
 
    DBUG_RETURN(data->type == TL_UNLOCK);       /* Test if Aborted */
 
1128
    return(data->type == TL_UNLOCK);    /* Test if Aborted */
1206
1129
  }
1207
1130
  check_locks(lock,"before upgrading lock",0);
1208
1131
  /* TODO:  Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
1216
1139
      if (data->lock->get_status)
1217
1140
        (*data->lock->get_status)(data->status_param, 0);
1218
1141
      pthread_mutex_unlock(&lock->mutex);
1219
 
      DBUG_RETURN(0);
 
1142
      return(0);
1220
1143
    }
1221
1144
 
1222
1145
    if (((*data->prev)=data->next))             /* remove from lock-list */
1236
1159
  {
1237
1160
    check_locks(lock,"waiting for lock",0);
1238
1161
  }
1239
 
  DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1));
 
1162
  return(wait_for_lock(&lock->write_wait,data,1));
1240
1163
}
1241
1164
 
1242
1165
 
1243
1166
/* downgrade a WRITE lock to a WRITE_DELAY lock if there is pending locks */
1244
1167
 
1245
 
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
 
1168
bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
1246
1169
{
1247
1170
  THR_LOCK *lock=data->lock;
1248
 
  DBUG_ENTER("thr_reschedule_write_lock");
1249
1171
 
1250
1172
  pthread_mutex_lock(&lock->mutex);
1251
1173
  if (!lock->read_wait.data)                    /* No waiting read locks */
1252
1174
  {
1253
1175
    pthread_mutex_unlock(&lock->mutex);
1254
 
    DBUG_RETURN(0);
 
1176
    return(0);
1255
1177
  }
1256
1178
 
1257
1179
  data->type=TL_WRITE_DELAYED;
1272
1194
  free_all_read_locks(lock,0);
1273
1195
 
1274
1196
  pthread_mutex_unlock(&lock->mutex);
1275
 
  DBUG_RETURN(thr_upgrade_write_delay_lock(data));
 
1197
  return(thr_upgrade_write_delay_lock(data));
1276
1198
}
1277
1199
 
1278
1200
 
1279
1201
#include <my_sys.h>
1280
1202
 
1281
 
static void thr_print_lock(const char* name,struct st_lock_list *list)
1282
 
{
1283
 
  THR_LOCK_DATA *data,**prev;
1284
 
  uint count=0;
1285
 
 
1286
 
  if (list->data)
1287
 
  {
1288
 
    printf("%-10s: ",name);
1289
 
    prev= &list->data;
1290
 
    for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
1291
 
    {
1292
 
      printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
1293
 
             (int) data->type);
1294
 
      if (data->prev != prev)
1295
 
        printf("\nWarning: prev didn't point at previous lock\n");
1296
 
      prev= &data->next;
1297
 
    }
1298
 
    puts("");
1299
 
    if (prev != list->last)
1300
 
      printf("Warning: last didn't point at last lock\n");
1301
 
  }
1302
 
}
1303
 
 
1304
 
void thr_print_locks(void)
1305
 
{
1306
 
  LIST *list;
1307
 
  uint count=0;
1308
 
 
1309
 
  pthread_mutex_lock(&THR_LOCK_lock);
1310
 
  puts("Current locks:");
1311
 
  for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
1312
 
       list= list_rest(list))
1313
 
  {
1314
 
    THR_LOCK *lock=(THR_LOCK*) list->data;
1315
 
    VOID(pthread_mutex_lock(&lock->mutex));
1316
 
    printf("lock: 0x%lx:",(ulong) lock);
1317
 
    if ((lock->write_wait.data || lock->read_wait.data) &&
1318
 
        (! lock->read.data && ! lock->write.data))
1319
 
      printf(" WARNING: ");
1320
 
    if (lock->write.data)
1321
 
      printf(" write");
1322
 
    if (lock->write_wait.data)
1323
 
      printf(" write_wait");
1324
 
    if (lock->read.data)
1325
 
      printf(" read");
1326
 
    if (lock->read_wait.data)
1327
 
      printf(" read_wait");
1328
 
    puts("");
1329
 
    thr_print_lock("write",&lock->write);
1330
 
    thr_print_lock("write_wait",&lock->write_wait);
1331
 
    thr_print_lock("read",&lock->read);
1332
 
    thr_print_lock("read_wait",&lock->read_wait);
1333
 
    VOID(pthread_mutex_unlock(&lock->mutex));
1334
 
    puts("");
1335
 
  }
1336
 
  fflush(stdout);
1337
 
  pthread_mutex_unlock(&THR_LOCK_lock);
1338
 
}
1339
 
 
1340
1203
/*****************************************************************************
1341
1204
** Test of thread locks
1342
1205
****************************************************************************/
1394
1257
static pthread_cond_t COND_thread_count;
1395
1258
static pthread_mutex_t LOCK_thread_count;
1396
1259
static uint thread_count;
1397
 
static ulong sum=0;
 
1260
static uint32_t sum=0;
1398
1261
 
1399
1262
#define MAX_LOCK_COUNT 8
1400
1263
 
1414
1277
{
1415
1278
}
1416
1279
 
1417
 
static my_bool test_check_status(void* param __attribute__((unused)))
 
1280
static bool test_check_status(void* param __attribute__((unused)))
1418
1281
{
1419
1282
  return 0;
1420
1283
}
1453
1316
        sleep(2);
1454
1317
      else
1455
1318
      {
1456
 
        ulong k;
1457
 
        for (k=0 ; k < (ulong) (tmp-2)*100000L ; k++)
 
1319
        uint32_t k;
 
1320
        for (k=0 ; k < (uint32_t) (tmp-2)*100000L ; k++)
1458
1321
          sum+=k;
1459
1322
      }
1460
1323
    }
1466
1329
  thr_print_locks();
1467
1330
  pthread_mutex_lock(&LOCK_thread_count);
1468
1331
  thread_count--;
1469
 
  VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
 
1332
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
1470
1333
  pthread_mutex_unlock(&LOCK_thread_count);
1471
1334
  free((uchar*) arg);
1472
1335
  return 0;
1479
1342
  pthread_attr_t thr_attr;
1480
1343
  int i,*param,error;
1481
1344
  MY_INIT(argv[0]);
1482
 
  if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
1483
 
    DBUG_PUSH(argv[1]+2);
1484
1345
 
1485
1346
  printf("Main thread: %s\n",my_thread_name());
1486
1347
 
1527
1388
  }
1528
1389
#endif
1529
1390
#ifdef HAVE_THR_SETCONCURRENCY
1530
 
  VOID(thr_setconcurrency(2));
 
1391
  thr_setconcurrency(2);
1531
1392
#endif
1532
1393
  for (i=0 ; i < (int) array_elements(lock_counts) ; i++)
1533
1394
  {