~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/os/os0sync.c

  • Committer: Monty Taylor
  • Date: 2009-08-12 06:25:19 UTC
  • mto: (1114.1.1 innodb-plugin-merge)
  • mto: This revision was merged to the branch mainline in revision 1183.
  • Revision ID: mordred@inaugust.com-20090812062519-cij02mrrunvnxblt
Tags: innodb-plugin-1.0.4
InnoDB Plugin 1.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/******************************************************
 
19
/**************************************************//**
 
20
@file os/os0sync.c
20
21
The interface to the operating system
21
22
synchronization primitives.
22
23
 
37
38
 
38
39
/* Type definition for an operating system mutex struct */
39
40
struct os_mutex_struct{
40
 
        os_event_t      event;  /* Used by sync0arr.c for queing threads */
41
 
        void*           handle; /* OS handle to mutex */
42
 
        ulint           count;  /* we use this counter to check
 
41
        os_event_t      event;  /*!< Used by sync0arr.c for queing threads */
 
42
        void*           handle; /*!< OS handle to mutex */
 
43
        ulint           count;  /*!< we use this counter to check
43
44
                                that the same thread does not
44
45
                                recursively lock the mutex: we
45
46
                                do not assume that the OS mutex
49
50
                                /* list of all 'slow' OS mutexes created */
50
51
};
51
52
 
52
 
/* Mutex protecting counts and the lists of OS mutexes and events */
 
53
/** Mutex protecting counts and the lists of OS mutexes and events */
53
54
UNIV_INTERN os_mutex_t  os_sync_mutex;
 
55
/** TRUE if os_sync_mutex has been initialized */
54
56
static ibool            os_sync_mutex_inited    = FALSE;
 
57
/** TRUE when os_sync_free() is being executed */
55
58
static ibool            os_sync_free_called     = FALSE;
56
59
 
57
 
/* This is incremented by 1 in os_thread_create and decremented by 1 in
 
60
/** This is incremented by 1 in os_thread_create and decremented by 1 in
58
61
os_thread_exit */
59
62
UNIV_INTERN ulint       os_thread_count         = 0;
60
63
 
61
 
/* The list of all events created */
 
64
/** The list of all events created */
62
65
static UT_LIST_BASE_NODE_T(os_event_struct_t)   os_event_list;
63
66
 
64
 
/* The list of all OS 'slow' mutexes */
 
67
/** The list of all OS 'slow' mutexes */
65
68
static UT_LIST_BASE_NODE_T(os_mutex_str_t)      os_mutex_list;
66
69
 
67
70
UNIV_INTERN ulint       os_event_count          = 0;
73
76
This version of the free event function doesn't acquire the global lock */
74
77
static void os_event_free_internal(os_event_t   event);
75
78
 
76
 
/*************************************************************
 
79
/*********************************************************//**
77
80
Initializes global event and OS 'slow' mutex lists. */
78
81
UNIV_INTERN
79
82
void
88
91
        os_sync_mutex_inited = TRUE;
89
92
}
90
93
 
91
 
/*************************************************************
 
94
/*********************************************************//**
92
95
Frees created events and OS 'slow' mutexes. */
93
96
UNIV_INTERN
94
97
void
125
128
        os_sync_free_called = FALSE;
126
129
}
127
130
 
128
 
/*************************************************************
 
131
/*********************************************************//**
129
132
Creates an event semaphore, i.e., a semaphore which may just have two
130
133
states: signaled and nonsignaled. The created event is manual reset: it
131
 
must be reset explicitly by calling sync_os_reset_event. */
 
134
must be reset explicitly by calling sync_os_reset_event.
 
135
@return the event handle */
132
136
UNIV_INTERN
133
137
os_event_t
134
138
os_event_create(
135
139
/*============*/
136
 
                                /* out: the event handle */
137
 
        const char*     name)   /* in: the name of the event, if NULL
 
140
        const char*     name)   /*!< in: the name of the event, if NULL
138
141
                                the event is created without a name */
139
142
{
140
143
#ifdef __WIN__
161
164
 
162
165
        os_fast_mutex_init(&(event->os_mutex));
163
166
 
164
 
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
165
 
        ut_a(0 == pthread_cond_init(&(event->cond_var),
166
 
                                    pthread_condattr_default));
167
 
#else
168
167
        ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
169
 
#endif
 
168
 
170
169
        event->is_set = FALSE;
171
170
 
172
171
        /* We return this value in os_event_reset(), which can then be
197
196
        return(event);
198
197
}
199
198
 
200
 
#ifdef __WIN__
201
 
/*************************************************************
202
 
Creates an auto-reset event semaphore, i.e., an event which is automatically
203
 
reset when a single thread is released. Works only in Windows. */
204
 
UNIV_INTERN
205
 
os_event_t
206
 
os_event_create_auto(
207
 
/*=================*/
208
 
                                /* out: the event handle */
209
 
        const char*     name)   /* in: the name of the event, if NULL
210
 
                                the event is created without a name */
211
 
{
212
 
        os_event_t event;
213
 
 
214
 
        event = ut_malloc(sizeof(struct os_event_struct));
215
 
 
216
 
        event->handle = CreateEvent(NULL, /* No security attributes */
217
 
                                    FALSE, /* Auto-reset */
218
 
                                    FALSE, /* Initial state nonsignaled */
219
 
                                    (LPCTSTR) name);
220
 
 
221
 
        if (!event->handle) {
222
 
                fprintf(stderr,
223
 
                        "InnoDB: Could not create a Windows auto"
224
 
                        " event semaphore; Windows error %lu\n",
225
 
                        (ulong) GetLastError());
226
 
        }
227
 
 
228
 
        /* Put to the list of events */
229
 
        os_mutex_enter(os_sync_mutex);
230
 
 
231
 
        UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
232
 
 
233
 
        os_event_count++;
234
 
 
235
 
        os_mutex_exit(os_sync_mutex);
236
 
 
237
 
        return(event);
238
 
}
239
 
#endif
240
 
 
241
 
/**************************************************************
 
199
/**********************************************************//**
242
200
Sets an event semaphore to the signaled state: lets waiting threads
243
201
proceed. */
244
202
UNIV_INTERN
245
203
void
246
204
os_event_set(
247
205
/*=========*/
248
 
        os_event_t      event)  /* in: event to set */
 
206
        os_event_t      event)  /*!< in: event to set */
249
207
{
250
208
#ifdef __WIN__
251
209
        ut_a(event);
267
225
#endif
268
226
}
269
227
 
270
 
/**************************************************************
 
228
/**********************************************************//**
271
229
Resets an event semaphore to the nonsignaled state. Waiting threads will
272
230
stop to wait for the event.
273
231
The return value should be passed to os_even_wait_low() if it is desired
274
232
that this thread should not wait in case of an intervening call to
275
233
os_event_set() between this os_event_reset() and the
276
 
os_event_wait_low() call. See comments for os_event_wait_low(). */
 
234
os_event_wait_low() call. See comments for os_event_wait_low().
 
235
@return current signal_count. */
277
236
UNIV_INTERN
278
237
ib_int64_t
279
238
os_event_reset(
280
239
/*===========*/
281
 
                                /* out: current signal_count. */
282
 
        os_event_t      event)  /* in: event to reset */
 
240
        os_event_t      event)  /*!< in: event to reset */
283
241
{
284
242
        ib_int64_t      ret = 0;
285
243
 
304
262
        return(ret);
305
263
}
306
264
 
307
 
/**************************************************************
 
265
/**********************************************************//**
308
266
Frees an event object, without acquiring the global lock. */
309
267
static
310
268
void
311
269
os_event_free_internal(
312
270
/*===================*/
313
 
        os_event_t      event)  /* in: event to free */
 
271
        os_event_t      event)  /*!< in: event to free */
314
272
{
315
273
#ifdef __WIN__
316
274
        ut_a(event);
333
291
        ut_free(event);
334
292
}
335
293
 
336
 
/**************************************************************
 
294
/**********************************************************//**
337
295
Frees an event object. */
338
296
UNIV_INTERN
339
297
void
340
298
os_event_free(
341
299
/*==========*/
342
 
        os_event_t      event)  /* in: event to free */
 
300
        os_event_t      event)  /*!< in: event to free */
343
301
 
344
302
{
345
303
#ifdef __WIN__
365
323
        ut_free(event);
366
324
}
367
325
 
368
 
/**************************************************************
 
326
/**********************************************************//**
369
327
Waits for an event object until it is in the signaled state. If
370
328
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
371
329
waiting thread when the event becomes signaled (or immediately if the
389
347
void
390
348
os_event_wait_low(
391
349
/*==============*/
392
 
        os_event_t      event,          /* in: event to wait */
393
 
        ib_int64_t      reset_sig_count)/* in: zero or the value
 
350
        os_event_t      event,          /*!< in: event to wait */
 
351
        ib_int64_t      reset_sig_count)/*!< in: zero or the value
394
352
                                        returned by previous call of
395
353
                                        os_event_reset(). */
396
354
{
444
402
#endif
445
403
}
446
404
 
447
 
/**************************************************************
 
405
/**********************************************************//**
448
406
Waits for an event object until it is in the signaled state or
449
 
a timeout is exceeded. In Unix the timeout is always infinite. */
 
407
a timeout is exceeded. In Unix the timeout is always infinite.
 
408
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
450
409
UNIV_INTERN
451
410
ulint
452
411
os_event_wait_time(
453
412
/*===============*/
454
 
                                /* out: 0 if success, OS_SYNC_TIME_EXCEEDED if
455
 
                                timeout was exceeded */
456
 
        os_event_t      event,  /* in: event to wait */
457
 
        ulint           time)   /* in: timeout in microseconds, or
 
413
        os_event_t      event,  /*!< in: event to wait */
 
414
        ulint           time)   /*!< in: timeout in microseconds, or
458
415
                                OS_SYNC_INFINITE_TIME */
459
416
{
460
417
#ifdef __WIN__
490
447
}
491
448
 
492
449
#ifdef __WIN__
493
 
/**************************************************************
 
450
/**********************************************************//**
494
451
Waits for any event in an OS native event array. Returns if even a single
495
 
one is signaled or becomes signaled. */
 
452
one is signaled or becomes signaled.
 
453
@return index of the event which was signaled */
496
454
UNIV_INTERN
497
455
ulint
498
456
os_event_wait_multiple(
499
457
/*===================*/
500
 
                                        /* out: index of the event
501
 
                                        which was signaled */
502
 
        ulint                   n,      /* in: number of events in the
 
458
        ulint                   n,      /*!< in: number of events in the
503
459
                                        array */
504
460
        os_native_event_t*      native_event_array)
505
 
                                        /* in: pointer to an array of event
 
461
                                        /*!< in: pointer to an array of event
506
462
                                        handles */
507
463
{
508
464
        DWORD   index;
514
470
                                       FALSE,      /* Wait for any 1 event */
515
471
                                       INFINITE); /* Infinite wait time
516
472
                                                  limit */
517
 
        ut_a(index >= WAIT_OBJECT_0);   /* NOTE: Pointless comparision */
 
473
        ut_a(index >= WAIT_OBJECT_0);   /* NOTE: Pointless comparison */
518
474
        ut_a(index < WAIT_OBJECT_0 + n);
519
475
 
520
476
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
525
481
}
526
482
#endif
527
483
 
528
 
/*************************************************************
 
484
/*********************************************************//**
529
485
Creates an operating system mutex semaphore. Because these are slow, the
530
 
mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
 
486
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
 
487
@return the mutex handle */
531
488
UNIV_INTERN
532
489
os_mutex_t
533
490
os_mutex_create(
534
491
/*============*/
535
 
                                /* out: the mutex handle */
536
 
        const char*     name)   /* in: the name of the mutex, if NULL
 
492
        const char*     name)   /*!< in: the name of the mutex, if NULL
537
493
                                the mutex is created without a name */
538
494
{
539
495
#ifdef __WIN__
576
532
        return(mutex_str);
577
533
}
578
534
 
579
 
/**************************************************************
 
535
/**********************************************************//**
580
536
Acquires ownership of a mutex semaphore. */
581
537
UNIV_INTERN
582
538
void
583
539
os_mutex_enter(
584
540
/*===========*/
585
 
        os_mutex_t      mutex)  /* in: mutex to acquire */
 
541
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
586
542
{
587
543
#ifdef __WIN__
588
544
        DWORD   err;
605
561
#endif
606
562
}
607
563
 
608
 
/**************************************************************
 
564
/**********************************************************//**
609
565
Releases ownership of a mutex. */
610
566
UNIV_INTERN
611
567
void
612
568
os_mutex_exit(
613
569
/*==========*/
614
 
        os_mutex_t      mutex)  /* in: mutex to release */
 
570
        os_mutex_t      mutex)  /*!< in: mutex to release */
615
571
{
616
572
        ut_a(mutex);
617
573
 
625
581
#endif
626
582
}
627
583
 
628
 
/**************************************************************
 
584
/**********************************************************//**
629
585
Frees a mutex object. */
630
586
UNIV_INTERN
631
587
void
632
588
os_mutex_free(
633
589
/*==========*/
634
 
        os_mutex_t      mutex)  /* in: mutex to free */
 
590
        os_mutex_t      mutex)  /*!< in: mutex to free */
635
591
{
636
592
        ut_a(mutex);
637
593
 
662
618
#endif
663
619
}
664
620
 
665
 
/*************************************************************
 
621
/*********************************************************//**
666
622
Initializes an operating system fast mutex semaphore. */
667
623
UNIV_INTERN
668
624
void
669
625
os_fast_mutex_init(
670
626
/*===============*/
671
 
        os_fast_mutex_t*        fast_mutex)     /* in: fast mutex */
 
627
        os_fast_mutex_t*        fast_mutex)     /*!< in: fast mutex */
672
628
{
673
629
#ifdef __WIN__
674
630
        ut_a(fast_mutex);
675
631
 
676
632
        InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
677
633
#else
678
 
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
679
 
        ut_a(0 == pthread_mutex_init(fast_mutex, pthread_mutexattr_default));
680
 
#else
681
634
        ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
682
635
#endif
683
 
#endif
684
636
        if (UNIV_LIKELY(os_sync_mutex_inited)) {
685
637
                /* When creating os_sync_mutex itself (in Unix) we cannot
686
638
                reserve it */
695
647
        }
696
648
}
697
649
 
698
 
/**************************************************************
 
650
/**********************************************************//**
699
651
Acquires ownership of a fast mutex. */
700
652
UNIV_INTERN
701
653
void
702
654
os_fast_mutex_lock(
703
655
/*===============*/
704
 
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to acquire */
 
656
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to acquire */
705
657
{
706
658
#ifdef __WIN__
707
659
        EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
710
662
#endif
711
663
}
712
664
 
713
 
/**************************************************************
 
665
/**********************************************************//**
714
666
Releases ownership of a fast mutex. */
715
667
UNIV_INTERN
716
668
void
717
669
os_fast_mutex_unlock(
718
670
/*=================*/
719
 
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to release */
 
671
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to release */
720
672
{
721
673
#ifdef __WIN__
722
674
        LeaveCriticalSection(fast_mutex);
725
677
#endif
726
678
}
727
679
 
728
 
/**************************************************************
 
680
/**********************************************************//**
729
681
Frees a mutex object. */
730
682
UNIV_INTERN
731
683
void
732
684
os_fast_mutex_free(
733
685
/*===============*/
734
 
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to free */
 
686
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to free */
735
687
{
736
688
#ifdef __WIN__
737
689
        ut_a(fast_mutex);