summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-10-04 15:42:16 +0300
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2010-10-04 15:42:16 +0300
commit8789c7972339340feb6a49903ff247de580bc5dd (patch)
tree0b41fbab5c8e486500b5c53bbe818e62f6f583f2 /include
parent5f9c629da0c08cd742a16419f4f66cdb18505302 (diff)
parent40ee088f68a452ac2ed19622481c73d6d38c7ec3 (diff)
downloadmariadb-git-8789c7972339340feb6a49903ff247de580bc5dd.tar.gz
merge
Diffstat (limited to 'include')
-rw-r--r--include/my_global.h1
-rw-r--r--include/my_pthread.h186
-rw-r--r--include/mysql.h3
-rw-r--r--include/mysql.h.pp3
-rw-r--r--include/mysql/psi/mysql_thread.h88
-rw-r--r--include/mysql/service_my_snprintf.h2
-rw-r--r--include/mysql_embed.h1
7 files changed, 141 insertions, 143 deletions
diff --git a/include/my_global.h b/include/my_global.h
index 378afe79904..ce32ac07372 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1484,7 +1484,6 @@ static inline double rint(double x)
/* Things we don't need in the embedded version of MySQL */
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
-#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_OPENSSL
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 5cf181596ad..d3053b4861a 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -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;
@@ -594,7 +605,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))
@@ -606,49 +617,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.
-
- Required by some algorithms in order to provide correctness.
+/**
+ Portable implementation of special type of read-write locks.
+
+ 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 */
@@ -656,13 +741,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 *);
diff --git a/include/mysql.h b/include/mysql.h
index 7d949597702..b52235b484e 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -214,7 +214,8 @@ struct st_mysql_options {
enum mysql_status
{
- MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
+ MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT,
+ MYSQL_STATUS_STATEMENT_GET_RESULT
};
enum mysql_protocol_type
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 7200a04d304..0a5c3d83148 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -298,7 +298,8 @@ struct st_mysql_options {
};
enum mysql_status
{
- MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
+ MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT,
+ MYSQL_STATUS_STATEMENT_GET_RESULT
};
enum mysql_protocol_type
{
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
index 60b4f5d6ef4..5b8ea3dc5dc 100644
--- a/include/mysql/psi/mysql_thread.h
+++ b/include/mysql/psi/mysql_thread.h
@@ -141,9 +141,7 @@ typedef struct st_mysql_rwlock mysql_rwlock_t;
@c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
@sa mysql_prlock_init
@sa mysql_prlock_rdlock
- @sa mysql_prlock_tryrdlock
@sa mysql_prlock_wrlock
- @sa mysql_prlock_trywrlock
@sa mysql_prlock_unlock
@sa mysql_prlock_destroy
*/
@@ -421,20 +419,6 @@ typedef struct st_mysql_cond mysql_cond_t;
#endif
/**
- @def mysql_prlock_tryrdlock(RW)
- Instrumented rw_pr_tryrdlock.
- @c mysql_prlock_tryrdlock is a drop-in replacement
- for @c rw_pr_tryrdlock.
-*/
-#ifdef HAVE_PSI_INTERFACE
- #define mysql_prlock_tryrdlock(RW) \
- inline_mysql_prlock_tryrdlock(RW, __FILE__, __LINE__)
-#else
- #define mysql_prlock_tryrdlock(RW) \
- inline_mysql_prlock_tryrdlock(RW)
-#endif
-
-/**
@def mysql_rwlock_trywrlock(RW)
Instrumented rwlock_trywrlock.
@c mysql_rwlock_trywrlock is a drop-in replacement
@@ -449,20 +433,6 @@ typedef struct st_mysql_cond mysql_cond_t;
#endif
/**
- @def mysql_prlock_trywrlock(RW)
- Instrumented rw_pr_trywrlock.
- @c mysql_prlock_trywrlock is a drop-in replacement
- for @c rw_pr_trywrlock.
-*/
-#ifdef HAVE_PSI_INTERFACE
- #define mysql_prlock_trywrlock(RW) \
- inline_mysql_prlock_trywrlock(RW, __FILE__, __LINE__)
-#else
- #define mysql_prlock_trywrlock(RW) \
- inline_mysql_prlock_trywrlock(RW)
-#endif
-
-/**
@def mysql_rwlock_unlock(RW)
Instrumented rwlock_unlock.
@c mysql_rwlock_unlock is a drop-in replacement
@@ -905,35 +875,6 @@ static inline int inline_mysql_rwlock_tryrdlock(
return result;
}
-#ifndef DISABLE_MYSQL_PRLOCK_H
-static inline int inline_mysql_prlock_tryrdlock(
- mysql_prlock_t *that
-#ifdef HAVE_PSI_INTERFACE
- , const char *src_file, uint src_line
-#endif
- )
-{
- int result;
-#ifdef HAVE_PSI_INTERFACE
- struct PSI_rwlock_locker *locker= NULL;
- PSI_rwlock_locker_state state;
- if (likely(PSI_server && that->m_psi))
- {
- locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
- PSI_RWLOCK_TRYREADLOCK);
- if (likely(locker != NULL))
- PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
- }
-#endif
- result= rw_pr_tryrdlock(&that->m_prlock);
-#ifdef HAVE_PSI_INTERFACE
- if (likely(locker != NULL))
- PSI_server->end_rwlock_rdwait(locker, result);
-#endif
- return result;
-}
-#endif
-
static inline int inline_mysql_rwlock_trywrlock(
mysql_rwlock_t *that
#ifdef HAVE_PSI_INTERFACE
@@ -961,35 +902,6 @@ static inline int inline_mysql_rwlock_trywrlock(
return result;
}
-#ifndef DISABLE_MYSQL_PRLOCK_H
-static inline int inline_mysql_prlock_trywrlock(
- mysql_prlock_t *that
-#ifdef HAVE_PSI_INTERFACE
- , const char *src_file, uint src_line
-#endif
- )
-{
- int result;
-#ifdef HAVE_PSI_INTERFACE
- struct PSI_rwlock_locker *locker= NULL;
- PSI_rwlock_locker_state state;
- if (likely(PSI_server && that->m_psi))
- {
- locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
- PSI_RWLOCK_TRYWRITELOCK);
- if (likely(locker != NULL))
- PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
- }
-#endif
- result= rw_pr_trywrlock(&that->m_prlock);
-#ifdef HAVE_PSI_INTERFACE
- if (likely(locker != NULL))
- PSI_server->end_rwlock_wrwait(locker, result);
-#endif
- return result;
-}
-#endif
-
static inline int inline_mysql_rwlock_unlock(
mysql_rwlock_t *that)
{
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
index d7f8d07e110..f6b4aa39dc5 100644
--- a/include/mysql/service_my_snprintf.h
+++ b/include/mysql/service_my_snprintf.h
@@ -53,7 +53,7 @@
<length modifier> can be 'l', 'll', or 'z'.
Supported formats are 's' (null pointer is accepted, printed as
- "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o',
+ "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o',
'X', 'p' (works as 0x%x).
Standard syntax for positional arguments $n is supported.
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index ae70b9723f8..e860a4486eb 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -23,7 +23,6 @@
/* Things we don't need in the embedded version of MySQL */
/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */
-#undef HAVE_PSTACK /* No stacktrace */
#undef HAVE_DLOPEN /* No udf functions */
#undef HAVE_SMEM /* No shared memory */
#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */