mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
5.5-merge
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
|
||||
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -48,19 +48,30 @@ typedef struct st_pthread_link {
|
||||
struct st_pthread_link *next;
|
||||
} pthread_link;
|
||||
|
||||
typedef struct {
|
||||
uint32 waiting;
|
||||
CRITICAL_SECTION lock_waiting;
|
||||
|
||||
enum {
|
||||
SIGNAL= 0,
|
||||
BROADCAST= 1,
|
||||
MAX_EVENTS= 2
|
||||
} EVENTS;
|
||||
|
||||
HANDLE events[MAX_EVENTS];
|
||||
HANDLE broadcast_block_event;
|
||||
/**
|
||||
Implementation of Windows condition variables.
|
||||
We use native conditions on Vista and later, and fallback to own
|
||||
implementation on earlier OS version.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/* Native condition (used on Vista and later) */
|
||||
CONDITION_VARIABLE native_cond;
|
||||
|
||||
/* Own implementation (used on XP) */
|
||||
struct
|
||||
{
|
||||
uint32 waiting;
|
||||
CRITICAL_SECTION lock_waiting;
|
||||
enum
|
||||
{
|
||||
SIGNAL= 0,
|
||||
BROADCAST= 1,
|
||||
MAX_EVENTS= 2
|
||||
} EVENTS;
|
||||
HANDLE events[MAX_EVENTS];
|
||||
HANDLE broadcast_block_event;
|
||||
};
|
||||
} pthread_cond_t;
|
||||
|
||||
|
||||
@@ -206,7 +217,11 @@ int pthread_cancel(pthread_t thread);
|
||||
typedef void *(* pthread_handler)(void *);
|
||||
|
||||
#define my_pthread_once_t pthread_once_t
|
||||
#if defined(PTHREAD_ONCE_INITIALIZER)
|
||||
#define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INITIALIZER
|
||||
#else
|
||||
#define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
#endif
|
||||
#define my_pthread_once(C,F) pthread_once(C,F)
|
||||
|
||||
/* Test first for RTS or FSU threads */
|
||||
@@ -488,7 +503,8 @@ int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
|
||||
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
|
||||
uint line);
|
||||
int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
|
||||
struct timespec *abstime, const char *file, uint line);
|
||||
const struct timespec *abstime,
|
||||
const char *file, uint line);
|
||||
void safe_mutex_global_init(void);
|
||||
void safe_mutex_end(FILE *file);
|
||||
void safe_mutex_free_deadlock_data(safe_mutex_t *mp);
|
||||
@@ -598,7 +614,7 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
|
||||
/* Use our own version of read/write locks */
|
||||
#define NEED_MY_RW_LOCK 1
|
||||
#define rw_lock_t my_rw_lock_t
|
||||
#define my_rwlock_init(A,B) my_rw_init((A), 0)
|
||||
#define my_rwlock_init(A,B) my_rw_init((A))
|
||||
#define rw_rdlock(A) my_rw_rdlock((A))
|
||||
#define rw_wrlock(A) my_rw_wrlock((A))
|
||||
#define rw_tryrdlock(A) my_rw_tryrdlock((A))
|
||||
@@ -610,49 +626,123 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
|
||||
#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
|
||||
|
||||
|
||||
/*
|
||||
Portable read-write locks which prefer readers.
|
||||
/**
|
||||
Portable implementation of special type of read-write locks.
|
||||
|
||||
Required by some algorithms in order to provide correctness.
|
||||
These locks have two properties which are unusual for rwlocks:
|
||||
1) They "prefer readers" in the sense that they do not allow
|
||||
situations in which rwlock is rd-locked and there is a
|
||||
pending rd-lock which is blocked (e.g. due to pending
|
||||
request for wr-lock).
|
||||
This is a stronger guarantee than one which is provided for
|
||||
PTHREAD_RWLOCK_PREFER_READER_NP rwlocks in Linux.
|
||||
MDL subsystem deadlock detector relies on this property for
|
||||
its correctness.
|
||||
2) They are optimized for uncontended wr-lock/unlock case.
|
||||
This is scenario in which they are most oftenly used
|
||||
within MDL subsystem. Optimizing for it gives significant
|
||||
performance improvements in some of tests involving many
|
||||
connections.
|
||||
|
||||
Another important requirement imposed on this type of rwlock
|
||||
by the MDL subsystem is that it should be OK to destroy rwlock
|
||||
object which is in unlocked state even though some threads might
|
||||
have not yet fully left unlock operation for it (of course there
|
||||
is an external guarantee that no thread will try to lock rwlock
|
||||
which is destroyed).
|
||||
Putting it another way the unlock operation should not access
|
||||
rwlock data after changing its state to unlocked.
|
||||
|
||||
TODO/FIXME: We should consider alleviating this requirement as
|
||||
it blocks us from doing certain performance optimizations.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
|
||||
/*
|
||||
On systems which have a way to specify that readers should
|
||||
be preferred through attribute mechanism (e.g. Linux) we use
|
||||
system implementation of read/write locks.
|
||||
*/
|
||||
#define rw_pr_lock_t pthread_rwlock_t
|
||||
typedef struct st_rw_pr_lock_t {
|
||||
/**
|
||||
Lock which protects the structure.
|
||||
Also held for the duration of wr-lock.
|
||||
*/
|
||||
pthread_mutex_t lock;
|
||||
/**
|
||||
Condition variable which is used to wake-up
|
||||
writers waiting for readers to go away.
|
||||
*/
|
||||
pthread_cond_t no_active_readers;
|
||||
/** Number of active readers. */
|
||||
uint active_readers;
|
||||
/** Number of writers waiting for readers to go away. */
|
||||
uint writers_waiting_readers;
|
||||
/** Indicates whether there is an active writer. */
|
||||
my_bool active_writer;
|
||||
#ifdef SAFE_MUTEX
|
||||
/** Thread holding wr-lock (for debug purposes only). */
|
||||
pthread_t writer_thread;
|
||||
#endif
|
||||
} rw_pr_lock_t;
|
||||
|
||||
extern int rw_pr_init(rw_pr_lock_t *);
|
||||
#define rw_pr_rdlock(A) pthread_rwlock_rdlock(A)
|
||||
#define rw_pr_wrlock(A) pthread_rwlock_wrlock(A)
|
||||
#define rw_pr_tryrdlock(A) pthread_rwlock_tryrdlock(A)
|
||||
#define rw_pr_trywrlock(A) pthread_rwlock_trywrlock(A)
|
||||
#define rw_pr_unlock(A) pthread_rwlock_unlock(A)
|
||||
#define rw_pr_destroy(A) pthread_rwlock_destroy(A)
|
||||
extern int rw_pr_rdlock(rw_pr_lock_t *);
|
||||
extern int rw_pr_wrlock(rw_pr_lock_t *);
|
||||
extern int rw_pr_unlock(rw_pr_lock_t *);
|
||||
extern int rw_pr_destroy(rw_pr_lock_t *);
|
||||
#ifdef SAFE_MUTEX
|
||||
#define rw_pr_lock_assert_write_owner(A) \
|
||||
DBUG_ASSERT((A)->active_writer && pthread_equal(pthread_self(), \
|
||||
(A)->writer_thread))
|
||||
#define rw_pr_lock_assert_not_write_owner(A) \
|
||||
DBUG_ASSERT(! (A)->active_writer || ! pthread_equal(pthread_self(), \
|
||||
(A)->writer_thread))
|
||||
#else
|
||||
#define rw_pr_lock_assert_write_owner(A)
|
||||
#define rw_pr_lock_assert_not_write_owner(A)
|
||||
#else
|
||||
/* Otherwise we have to use our own implementation of read/write locks. */
|
||||
#define NEED_MY_RW_LOCK 1
|
||||
struct st_my_rw_lock_t;
|
||||
#define rw_pr_lock_t my_rw_lock_t
|
||||
extern int rw_pr_init(struct st_my_rw_lock_t *);
|
||||
#define rw_pr_rdlock(A) my_rw_rdlock((A))
|
||||
#define rw_pr_wrlock(A) my_rw_wrlock((A))
|
||||
#define rw_pr_tryrdlock(A) my_rw_tryrdlock((A))
|
||||
#define rw_pr_trywrlock(A) my_rw_trywrlock((A))
|
||||
#define rw_pr_unlock(A) my_rw_unlock((A))
|
||||
#define rw_pr_destroy(A) my_rw_destroy((A))
|
||||
#define rw_pr_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A))
|
||||
#define rw_pr_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A))
|
||||
#endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */
|
||||
#endif /* SAFE_MUTEX */
|
||||
|
||||
|
||||
#ifdef NEED_MY_RW_LOCK
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/**
|
||||
Implementation of Windows rwlock.
|
||||
|
||||
We use native (slim) rwlocks on Win7 and later, and fallback to portable
|
||||
implementation on earlier Windows.
|
||||
|
||||
slim rwlock are also available on Vista/WS2008, but we do not use it
|
||||
("trylock" APIs are missing on Vista)
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/* Native rwlock (is_srwlock == TRUE) */
|
||||
struct
|
||||
{
|
||||
SRWLOCK srwlock; /* native reader writer lock */
|
||||
BOOL have_exclusive_srwlock; /* used for unlock */
|
||||
};
|
||||
|
||||
/*
|
||||
Portable implementation (is_srwlock == FALSE)
|
||||
Fields are identical with Unix my_rw_lock_t fields.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
pthread_mutex_t lock; /* lock for structure */
|
||||
pthread_cond_t readers; /* waiting readers */
|
||||
pthread_cond_t writers; /* waiting writers */
|
||||
int state; /* -1:writer,0:free,>0:readers */
|
||||
int waiters; /* number of waiting writers */
|
||||
#ifdef SAFE_MUTEX
|
||||
pthread_t write_thread;
|
||||
#endif
|
||||
};
|
||||
} my_rw_lock_t;
|
||||
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
/*
|
||||
On systems which don't support native read/write locks, or don't support
|
||||
read/write locks which prefer readers we have to use own implementation.
|
||||
On systems which don't support native read/write locks we have
|
||||
to use own implementation.
|
||||
*/
|
||||
typedef struct st_my_rw_lock_t {
|
||||
pthread_mutex_t lock; /* lock for structure */
|
||||
@@ -660,13 +750,14 @@ typedef struct st_my_rw_lock_t {
|
||||
pthread_cond_t writers; /* waiting writers */
|
||||
int state; /* -1:writer,0:free,>0:readers */
|
||||
int waiters; /* number of waiting writers */
|
||||
my_bool prefer_readers;
|
||||
#ifdef SAFE_MUTEX
|
||||
pthread_t write_thread;
|
||||
#endif
|
||||
} my_rw_lock_t;
|
||||
|
||||
extern int my_rw_init(my_rw_lock_t *, my_bool *);
|
||||
#endif /*! _WIN32 */
|
||||
|
||||
extern int my_rw_init(my_rw_lock_t *);
|
||||
extern int my_rw_destroy(my_rw_lock_t *);
|
||||
extern int my_rw_rdlock(my_rw_lock_t *);
|
||||
extern int my_rw_wrlock(my_rw_lock_t *);
|
||||
@@ -720,8 +811,7 @@ typedef ulong my_thread_id;
|
||||
|
||||
extern void my_threadattr_global_init(void);
|
||||
extern my_bool my_thread_global_init(void);
|
||||
extern my_bool my_thread_basic_global_init(void);
|
||||
extern void my_thread_basic_global_reinit(void);
|
||||
extern void my_thread_global_reinit(void);
|
||||
extern void my_thread_global_end(void);
|
||||
extern my_bool my_thread_init(void);
|
||||
extern void my_thread_end(void);
|
||||
@@ -800,12 +890,6 @@ extern uint thd_lib_detected;
|
||||
to use my_atomic operations instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
Warning:
|
||||
When compiling without threads, this file is not included.
|
||||
See the *other* declarations of thread_safe_xxx in include/my_global.h
|
||||
*/
|
||||
#ifdef THREAD
|
||||
#ifndef thread_safe_increment
|
||||
#ifdef _WIN32
|
||||
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
|
||||
@@ -829,7 +913,7 @@ extern uint thd_lib_detected;
|
||||
(mysql_mutex_lock((L)), (V)-=(C), mysql_mutex_unlock((L)))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
statistics_xxx functions are for non critical statistic,
|
||||
|
Reference in New Issue
Block a user