List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:November 7 2008 10:46am
Subject:bzr commit into mysql-6.0 branch (serg:2756)
View as plain text  
#At file:///usr/home/serg/Abk/mysql/6.0-maria/

 2756 Sergei Golubchik	2008-11-07 [merge]
      merge
modified:
  include/waiting_threads.h
  mysys/lf_hash.c
  mysys/waiting_threads.c

=== modified file 'include/waiting_threads.h'
--- a/include/waiting_threads.h	2008-10-27 22:23:34 +0000
+++ b/include/waiting_threads.h	2008-11-04 13:09:32 +0000
@@ -30,13 +30,11 @@ typedef struct st_wt_resource_type {
   const void *(*make_key)(WT_RESOURCE_ID *id, uint *len);
 } WT_RESOURCE_TYPE;
 
-/* we want to compare this struct with memcmp, make it packed */
-#pragma pack(1)
 struct st_wt_resource_id {
   ulonglong value;
   WT_RESOURCE_TYPE *type;
 };
-#pragma pack()
+#define sizeof_WT_RESOURCE_ID (sizeof(ulonglong)+sizeof(void*))
 
 #define WT_WAIT_STATS  24
 #define WT_CYCLE_STATS 32
@@ -82,7 +80,31 @@ typedef struct st_wt_resource {
 #ifdef WT_RWLOCKS_USE_MUTEXES
   /*
     we need a special rwlock-like 'lock' to allow readers bypass
-    waiting writers, otherwise readers can deadlock.
+    waiting writers, otherwise readers can deadlock. For example:
+
+      A waits on resource x, owned by B, B waits on resource y, owned
+      by A, we have a cycle (A->x->B->y->A)
+      Both A and B start deadlock detection:
+
+        A locks x                          B locks y
+        A goes deeper                      B goes deeper
+        A locks y                          B locks x
+
+      with mutexes it would deadlock. With rwlocks it won't, as long
+      as both A and B are taking read locks (and they do).
+      But other threads may take write locks. Assume there's
+      C who wants to start waiting on x, and D who wants to start
+      waiting on y.
+
+        A read-locks x                       B read-locks y
+        A goes deeper                        B goes deeper
+     => C write-locks x (to add a new edge)  D write-locks y
+     .. C is blocked                         D is blocked
+        A read-locks y                       B read-locks x
+
+      Now, if a read lock can bypass a pending wrote lock request, we're fine.
+      If it can not, we have a deadlock.
+
     writer starvation is technically possible, but unlikely, because
     the contention is expected to be low.
   */

=== modified file 'mysys/lf_hash.c'
--- a/mysys/lf_hash.c	2008-07-29 14:10:24 +0000
+++ b/mysys/lf_hash.c	2008-11-03 19:33:34 +0000
@@ -281,8 +281,9 @@ static inline const uchar* hash_key(cons
 }
 
 /*
-  compute the hash key value from the raw key.
-  note, that the hash value is limited to 2^31, because we need one
+  Compute the hash key value from the raw key.
+
+  @note, that the hash value is limited to 2^31, because we need one
   bit to distinguish between normal and dummy nodes.
 */
 static inline uint calc_hash(LF_HASH *hash, const uchar *key, uint keylen)
@@ -300,7 +301,7 @@ static int initialize_bucket(LF_HASH *, 
 /*
   Initializes lf_hash, the arguments are compatible with hash_init
 
-  @@note element_size sets both the size of allocated memory block for
+  @note element_size sets both the size of allocated memory block for
   lf_alloc and a size of memcpy'ed block size in lf_hash_insert. Typically
   they are the same, indeed. But LF_HASH::element_size can be decreased
   after lf_hash_init, and then lf_alloc will allocate larger block that

=== modified file 'mysys/waiting_threads.c'
--- a/mysys/waiting_threads.c	2008-10-24 10:34:08 +0000
+++ b/mysys/waiting_threads.c	2008-11-03 19:33:34 +0000
@@ -280,7 +280,7 @@ void wt_init()
   DBUG_ENTER("wt_init");
 
   lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0,
-               sizeof(struct st_wt_resource_id), 0, 0);
+               sizeof_WT_RESOURCE_ID, 0, 0);
   reshash.alloc.constructor= wt_resource_init;
   reshash.alloc.destructor= wt_resource_destroy;
   /*
@@ -396,9 +396,7 @@ void wt_thd_destroy(WT_THD *thd)
 */
 int wt_resource_id_memcmp(void *a, void *b)
 {
-  /* assert that the structure is not padded with random bytes */
-  compile_time_assert(sizeof(WT_RESOURCE_ID)==sizeof(ulonglong)+sizeof(void*));
-  return memcmp(a, b, sizeof(WT_RESOURCE_ID));
+  return memcmp(a, b, sizeof_WT_RESOURCE_ID);
 }
 
 /**
@@ -657,7 +655,7 @@ static int unlock_lock_and_free_resource
   /* XXX if (rc->id.type->make_key) key=
rc->id.type->make_key(&rc->id, &keylen); else */
   {
     key= &rc->id;
-    keylen= sizeof(rc->id);
+    keylen= sizeof_WT_RESOURCE_ID;
   }
 
   /*
@@ -751,7 +749,7 @@ int wt_thd_will_wait_for(WT_THD *thd, WT
     /* XXX if (restype->make_key) key= restype->make_key(resid, &keylen); else
*/
     {
       key= resid;
-      keylen= sizeof(*resid);
+      keylen= sizeof_WT_RESOURCE_ID;
     }
 
     DBUG_PRINT("wt", ("first blocker"));

Thread
bzr commit into mysql-6.0 branch (serg:2756) Sergei Golubchik7 Nov