~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Patrick Crews
  • Date: 2010-12-07 20:02:50 UTC
  • Revision ID: gleebix@gmail.com-20101207200250-6a27jgqalgw5bsb5
Added disabled.def file to disable drizzleslap due to Bug#684269.  Need to skip for tarball release this round

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
23
23
 
24
24
Created 9/6/1995 Heikki Tuuri
25
25
*******************************************************/
26
 
#include "univ.i"
27
 
 
28
 
#include <errno.h>
29
26
 
30
27
#include "os0sync.h"
31
28
#ifdef UNIV_NONINL
76
73
UNIV_INTERN ulint       os_mutex_count          = 0;
77
74
UNIV_INTERN ulint       os_fast_mutex_count     = 0;
78
75
 
79
 
/* The number of microsecnds in a second. */
80
 
static const ulint MICROSECS_IN_A_SECOND = 1000000;
81
 
 
82
76
/* Because a mutex is embedded inside an event and there is an
83
77
event embedded inside a mutex, on free, this generates a recursive call.
84
78
This version of the free event function doesn't acquire the global lock */
129
123
}
130
124
 
131
125
/*********************************************************//**
132
 
Do a timed wait on condition variable.
133
 
@return TRUE if timed out, FALSE otherwise */
134
 
UNIV_INLINE
135
 
ibool
136
 
os_cond_wait_timed(
137
 
/*===============*/
138
 
        os_cond_t*              cond,           /*!< in: condition variable. */
139
 
        os_fast_mutex_t*        mutex,          /*!< in: fast mutex */
140
 
#ifndef __WIN__
141
 
        const struct timespec*  abstime         /*!< in: timeout */
142
 
#else
143
 
        DWORD                   time_in_ms      /*!< in: timeout in
144
 
                                                milliseconds*/
145
 
#endif /* !__WIN__ */
146
 
)
147
 
{
148
 
#ifdef __WIN__
149
 
        BOOL    ret;
150
 
        DWORD   err;
151
 
 
152
 
        ut_a(sleep_condition_variable != NULL);
153
 
 
154
 
        ret = sleep_condition_variable(cond, mutex, time_in_ms);
155
 
 
156
 
        if (!ret) {
157
 
                err = GetLastError();
158
 
                /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
159
 
                "Condition variables are subject to spurious wakeups
160
 
                (those not associated with an explicit wake) and stolen wakeups
161
 
                (another thread manages to run before the woken thread)."
162
 
                Check for both types of timeouts.
163
 
                Conditions are checked by the caller.*/
164
 
                if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
165
 
                        return(TRUE);
166
 
                }
167
 
        }
168
 
 
169
 
        ut_a(ret);
170
 
 
171
 
        return(FALSE);
172
 
#else
173
 
        int     ret;
174
 
 
175
 
        ret = pthread_cond_timedwait(cond, mutex, abstime);
176
 
 
177
 
        switch (ret) {
178
 
        case 0:
179
 
        case ETIMEDOUT:
180
 
        /* We play it safe by checking for EINTR even though
181
 
        according to the POSIX documentation it can't return EINTR. */
182
 
        case EINTR:
183
 
                break;
184
 
 
185
 
        default:
186
 
                fprintf(stderr, "  InnoDB: pthread_cond_timedwait() returned: "
187
 
                                "%d: abstime={%lu,%lu}\n",
188
 
                                ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
189
 
                ut_error;
190
 
        }
191
 
 
192
 
        return(ret == ETIMEDOUT);
193
 
#endif
194
 
}
195
 
/*********************************************************//**
196
126
Wait on condition variable */
197
127
UNIV_INLINE
198
128
void
390
320
        {
391
321
                UT_NOT_USED(name);
392
322
 
393
 
                event = static_cast<os_event_struct*>(ut_malloc(sizeof(struct os_event_struct)));
 
323
                event = ut_malloc(sizeof(struct os_event_struct));
394
324
 
395
325
                os_fast_mutex_init(&(event->os_mutex));
396
326
 
643
573
        }
644
574
}
645
575
 
646
 
/**********************************************************//**
647
 
Waits for an event object until it is in the signaled state or
648
 
a timeout is exceeded.
649
 
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
650
 
UNIV_INTERN
651
 
ulint
652
 
os_event_wait_time_low(
653
 
/*===================*/
654
 
        os_event_t      event,                  /*!< in: event to wait */
655
 
        ulint           time_in_usec,           /*!< in: timeout in
656
 
                                                microseconds, or
657
 
                                                OS_SYNC_INFINITE_TIME */
658
 
        ib_int64_t      reset_sig_count)        /*!< in: zero or the value
659
 
                                                returned by previous call of
660
 
                                                os_event_reset(). */
661
 
 
662
 
{
663
 
        ibool           timed_out = FALSE;
664
 
        ib_int64_t      old_signal_count;
665
 
 
666
 
#ifdef __WIN__
667
 
        DWORD           time_in_ms;
668
 
 
669
 
        if (!srv_use_native_conditions) {
670
 
                DWORD   err;
671
 
 
672
 
                ut_a(event);
673
 
 
674
 
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
675
 
                        time_in_ms = time_in_usec / 1000;
676
 
                        err = WaitForSingleObject(event->handle, time_in_ms);
677
 
                } else {
678
 
                        err = WaitForSingleObject(event->handle, INFINITE);
679
 
                }
680
 
 
681
 
                if (err == WAIT_OBJECT_0) {
682
 
                        return(0);
683
 
                } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
684
 
                        return(OS_SYNC_TIME_EXCEEDED);
685
 
                }
686
 
 
687
 
                ut_error;
688
 
                /* Dummy value to eliminate compiler warning. */
689
 
                return(42);
690
 
        } else {
691
 
                ut_a(sleep_condition_variable != NULL);
692
 
 
693
 
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
694
 
                        time_in_ms = time_in_usec / 1000;
695
 
                } else {
696
 
                        time_in_ms = INFINITE;
697
 
                }
698
 
        }
699
 
#else
700
 
        struct timespec abstime;
701
 
 
702
 
        if (time_in_usec != OS_SYNC_INFINITE_TIME) {
703
 
                struct timeval  tv;
704
 
                int             ret;
705
 
                ulint           sec;
706
 
                ulint           usec;
707
 
 
708
 
                ret = ut_usectime(&sec, &usec);
709
 
                ut_a(ret == 0);
710
 
 
711
 
                tv.tv_sec = sec;
712
 
                tv.tv_usec = usec;
713
 
 
714
 
                tv.tv_usec += time_in_usec;
715
 
 
716
 
                if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
717
 
                        tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
718
 
                        tv.tv_usec %= MICROSECS_IN_A_SECOND;
719
 
                }
720
 
 
721
 
                abstime.tv_sec  = tv.tv_sec;
722
 
                abstime.tv_nsec = tv.tv_usec * 1000;
723
 
        } else {
724
 
                abstime.tv_nsec = 999999999;
725
 
                abstime.tv_sec = (time_t) ULINT_MAX;
726
 
        }
727
 
 
728
 
        ut_a(abstime.tv_nsec <= 999999999);
729
 
 
730
 
#endif /* __WIN__ */
731
 
 
732
 
        os_fast_mutex_lock(&event->os_mutex);
733
 
 
734
 
        if (reset_sig_count) {
735
 
                old_signal_count = reset_sig_count;
736
 
        } else {
737
 
                old_signal_count = event->signal_count;
738
 
        }
739
 
 
740
 
        do {
741
 
                if (event->is_set == TRUE
742
 
                    || event->signal_count != old_signal_count) {
743
 
 
744
 
                        break;
745
 
                }
746
 
 
747
 
                timed_out = os_cond_wait_timed(
748
 
                        &event->cond_var, &event->os_mutex,
749
 
#ifndef __WIN__
750
 
                        &abstime
751
 
#else
752
 
                        time_in_ms
753
 
#endif /* !__WIN__ */
754
 
                );
755
 
 
756
 
        } while (!timed_out);
757
 
 
758
 
        os_fast_mutex_unlock(&event->os_mutex);
759
 
 
760
 
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
761
 
 
762
 
                os_thread_exit(NULL);
763
 
        }
764
 
 
765
 
        return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
766
 
}
767
 
 
768
576
/*********************************************************//**
769
577
Creates an operating system mutex semaphore. Because these are slow, the
770
578
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
777
585
        os_fast_mutex_t*        mutex;
778
586
        os_mutex_t              mutex_str;
779
587
 
780
 
        mutex = static_cast<os_fast_mutex_t*>(ut_malloc(sizeof(os_fast_mutex_t)));
 
588
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
781
589
 
782
590
        os_fast_mutex_init(mutex);
783
 
        mutex_str = static_cast<os_mutex_t>(ut_malloc(sizeof(os_mutex_str_t)));
 
591
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
784
592
 
785
593
        mutex_str->handle = mutex;
786
594
        mutex_str->count = 0;
810
618
/*===========*/
811
619
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
812
620
{
813
 
        os_fast_mutex_lock(static_cast<os_fast_mutex_t *>(mutex->handle));
 
621
        os_fast_mutex_lock(mutex->handle);
814
622
 
815
623
        (mutex->count)++;
816
624
 
830
638
        ut_a(mutex->count == 1);
831
639
 
832
640
        (mutex->count)--;
833
 
        os_fast_mutex_unlock(static_cast<os_fast_mutex_t *>(mutex->handle));
 
641
        os_fast_mutex_unlock(mutex->handle);
834
642
}
835
643
 
836
644
/**********************************************************//**
859
667
                os_mutex_exit(os_sync_mutex);
860
668
        }
861
669
 
862
 
        os_fast_mutex_free(static_cast<os_fast_mutex_t *>(mutex->handle));
 
670
        os_fast_mutex_free(mutex->handle);
863
671
        ut_free(mutex->handle);
864
672
        ut_free(mutex);
865
673
}
877
685
 
878
686
        InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
879
687
#else
880
 
        ut_a(0 == pthread_mutex_init(fast_mutex, NULL));
 
688
        ut_a(0 == innobase_fast_mutex_init(fast_mutex));
881
689
#endif
882
690
        if (UNIV_LIKELY(os_sync_mutex_inited)) {
883
691
                /* When creating os_sync_mutex itself (in Unix) we cannot