From 7de7c38f2f1b678e6d1894b94dd9abe9de9d8c70 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Oct 2003 18:20:07 -0700 Subject: Many files: Improved concurrency for key cache reassignment include/my_sys.h: Improved concurrency for key cache reassignment include/myisam.h: Improved concurrency for key cache reassignment myisam/mi_keycache.c: Improved concurrency for key cache reassignment myisam/mi_locking.c: Improved concurrency for key cache reassignment mysys/mf_keycache.c: Improved concurrency for key cache reassignment sql/ha_myisam.cc: Improved concurrency for key cache reassignment sql/sql_table.cc: Improved concurrency for key cache reassignment --- myisam/mi_keycache.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'myisam/mi_keycache.c') diff --git a/myisam/mi_keycache.c b/myisam/mi_keycache.c index 1010aef9e1d..4b7d7d6b23f 100644 --- a/myisam/mi_keycache.c +++ b/myisam/mi_keycache.c @@ -39,24 +39,68 @@ of the table will be assigned to the specified key cache. */ +typedef struct st_assign_extra_info +{ + pthread_mutex_t *lock; + struct st_my_thread_var *waiting_thread; +} ASSIGN_EXTRA_INFO; + +static void remove_key_cache_assign(void *arg) +{ + KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) arg; + ASSIGN_EXTRA_INFO *extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info; + struct st_my_thread_var *waiting_thread; + pthread_mutex_t *lock= extra_info->lock; + pthread_mutex_lock(lock); + if (!(--key_cache->assignments) && + (waiting_thread = extra_info->waiting_thread)) + { + my_free(extra_info, MYF(0)); + key_cache->extra_info= 0; + if (waiting_thread != my_thread_var) + pthread_cond_signal(&waiting_thread->suspend); + } + pthread_mutex_unlock(lock); +} + int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map, - KEY_CACHE_HANDLE *reg_keycache) + KEY_CACHE_VAR *key_cache, + pthread_mutex_t *assign_lock) { + ASSIGN_EXTRA_INFO *extra_info; int error= 0; MYISAM_SHARE* share= info->s; DBUG_ENTER("mi_assign_to_keycache"); - share->reg_keycache= reg_keycache; + share->reg_keycache= &key_cache->cache; + pthread_mutex_lock(assign_lock); + if (!(extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info)) + { + if (!(extra_info= (ASSIGN_EXTRA_INFO*) my_malloc(sizeof(ASSIGN_EXTRA_INFO), + MYF(MY_WME | MY_ZEROFILL)))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + key_cache->extra_info= extra_info; + key_cache->action= remove_key_cache_assign; + extra_info->lock= assign_lock; + } + key_cache->assignments++; + pthread_mutex_unlock(assign_lock); + if (!(info->lock_type == F_WRLCK && share->w_locks)) { - if (flush_key_blocks(*share->keycache, share->kfile, FLUSH_RELEASE)) + if (flush_key_blocks(*share->keycache, share->kfile, FLUSH_REMOVE)) { error=my_errno; mi_mark_crashed(info); /* Mark that table must be checked */ } - share->keycache= reg_keycache; + share->keycache= &key_cache->cache; } + else + { + extra_info->waiting_thread= my_thread_var; + } + DBUG_RETURN(error); } -- cgit v1.2.1