diff options
-rw-r--r-- | mysys/lf_hash.c | 1 | ||||
-rw-r--r-- | mysys/waiting_threads.c | 49 | ||||
-rw-r--r-- | sql/table_cache.cc | 5 | ||||
-rw-r--r-- | sql/table_cache.h | 9 |
4 files changed, 37 insertions, 27 deletions
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index db84d1fba08..7bced68d34d 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -336,7 +336,6 @@ static void default_initializer(LF_HASH *hash, void *dst, const void *src) is expensive to initialize - for example if there is a mutex or DYNAMIC_ARRAY. In this case they should be initialize in the LF_ALLOCATOR::constructor, and lf_hash_insert should not overwrite them. - See wt_init() for example. The above works well with PODS. For more complex cases (e.g. C++ classes with private members) use initializer function. diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c index 23b4026b8f1..ae0ffe7f7eb 100644 --- a/mysys/waiting_threads.c +++ b/mysys/waiting_threads.c @@ -253,11 +253,7 @@ struct st_wt_resource { #ifndef DBUG_OFF mysql_mutex_t *cond_mutex; /* a mutex for the 'cond' below */ #endif - /* - before the 'lock' all elements are mutable, after (and including) - - immutable in the sense that lf_hash_insert() won't memcpy() over them. - See wt_init(). - */ + #ifdef WT_RWLOCKS_USE_MUTEXES /* we need a special rwlock-like 'lock' to allow readers bypass @@ -389,10 +385,10 @@ static LF_HASH reshash; It's called from lf_hash and takes a pointer to an LF_SLIST instance. WT_RESOURCE is located at arg+sizeof(LF_SLIST) */ -static void wt_resource_init(uchar *arg) +static void wt_resource_create(uchar *arg) { WT_RESOURCE *rc= (WT_RESOURCE*)(arg+LF_HASH_OVERHEAD); - DBUG_ENTER("wt_resource_init"); + DBUG_ENTER("wt_resource_create"); bzero(rc, sizeof(*rc)); rc_rwlock_init(rc); @@ -419,25 +415,37 @@ static void wt_resource_destroy(uchar *arg) DBUG_VOID_RETURN; } +/** + WT_RESOURCE initializer + + It's called from lf_hash when an element is inserted. +*/ +static void wt_resource_init(LF_HASH *hash __attribute__((unused)), + WT_RESOURCE *rc, WT_RESOURCE_ID *id) +{ + DBUG_ENTER("wt_resource_init"); + rc->id= *id; + rc->waiter_count= 0; + rc->state= ACTIVE; +#ifndef DBUG_OFF + rc->cond_mutex= 0; +#endif + DBUG_VOID_RETURN; +} + static int wt_init_done; void wt_init() { DBUG_ENTER("wt_init"); - DBUG_ASSERT(reshash.alloc.constructor != wt_resource_init); + DBUG_ASSERT(reshash.alloc.constructor != wt_resource_create); lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0, sizeof_WT_RESOURCE_ID, 0, 0); - reshash.alloc.constructor= wt_resource_init; + reshash.alloc.constructor= wt_resource_create; reshash.alloc.destructor= wt_resource_destroy; - /* - Note a trick: we initialize the hash with the real element size, - but fix it later to a shortened element size. This way - the allocator will allocate elements correctly, but - lf_hash_insert() will only overwrite part of the element with memcpy(). - lock, condition, and dynamic array will be intact. - */ - reshash.element_size= offsetof(WT_RESOURCE, lock); + reshash.initializer= (lf_hash_initializer) wt_resource_init; + bzero(wt_wait_stats, sizeof(wt_wait_stats)); bzero(wt_cycle_stats, sizeof(wt_cycle_stats)); wt_success_stats= 0; @@ -930,14 +938,9 @@ int wt_thd_will_wait_for(WT_THD *thd, WT_THD *blocker, retry: while ((rc= lf_hash_search(&reshash, thd->pins, key, keylen)) == 0) { - WT_RESOURCE tmp; - DBUG_PRINT("wt", ("failed to find rc in hash, inserting")); - bzero(&tmp, sizeof(tmp)); - tmp.id= *resid; - tmp.state= ACTIVE; - if (lf_hash_insert(&reshash, thd->pins, &tmp) == -1) /* if OOM */ + if (lf_hash_insert(&reshash, thd->pins, resid) == -1) /* if OOM */ DBUG_RETURN(WT_DEADLOCK); /* Two cases: either lf_hash_insert() failed - because another thread diff --git a/sql/table_cache.cc b/sql/table_cache.cc index 9a75cafb30e..2dd368a1945 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -432,7 +432,7 @@ void tdc_init(void) &my_charset_bin); tdc_hash.alloc.constructor= TDC_element::lf_alloc_constructor; tdc_hash.alloc.destructor= TDC_element::lf_alloc_destructor; - tdc_hash.element_size= offsetof(TDC_element, version); + tdc_hash.initializer= (lf_hash_initializer) TDC_element::lf_hash_initializer; DBUG_VOID_RETURN; } @@ -616,7 +616,7 @@ retry: while (!(element= (TDC_element*) lf_hash_search_using_hash_value(&tdc_hash, thd->tdc_hash_pins, hash_value, (uchar*) key, key_length))) { - TDC_element tmp(key, key_length); + LEX_STRING tmp= { const_cast<char*>(key), key_length }; int res= lf_hash_insert(&tdc_hash, thd->tdc_hash_pins, (uchar*) &tmp); if (res == -1) @@ -628,7 +628,6 @@ retry: thd->tdc_hash_pins, hash_value, (uchar*) key, key_length); lf_hash_search_unpin(thd->tdc_hash_pins); DBUG_ASSERT(element); - element->assert_clean_share(); if (!(share= alloc_table_share(db, table_name, key, key_length))) { diff --git a/sql/table_cache.h b/sql/table_cache.h index b829e4de752..2d70e4c90a5 100644 --- a/sql/table_cache.h +++ b/sql/table_cache.h @@ -166,6 +166,15 @@ public: } + static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)), + TDC_element *element, LEX_STRING *key) + { + memcpy(element->m_key, key->str, key->length); + element->m_key_length= key->length; + element->assert_clean_share(); + } + + static uchar *key(const TDC_element *element, size_t *length, my_bool not_used __attribute__((unused))) { |