Commit 2426972c authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

semaphores replaced by rwlock

parent e5b02fbe
...@@ -494,8 +494,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, ...@@ -494,8 +494,8 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
#define my_rwlock_init(A,B) pthread_rwlock_init((A),(B)) #define my_rwlock_init(A,B) pthread_rwlock_init((A),(B))
#define rw_rdlock(A) pthread_rwlock_rdlock(A) #define rw_rdlock(A) pthread_rwlock_rdlock(A)
#define rw_wrlock(A) pthread_rwlock_wrlock(A) #define rw_wrlock(A) pthread_rwlock_wrlock(A)
#define rw_tryrdlock(A) pthread_mutex_tryrdlock((A)) #define rw_tryrdlock(A) pthread_rwlock_tryrdlock((A))
#define rw_trywrlock(A) pthread_mutex_trywrlock((A)) #define rw_trywrlock(A) pthread_rwlock_trywrlock((A))
#define rw_unlock(A) pthread_rwlock_unlock(A) #define rw_unlock(A) pthread_rwlock_unlock(A)
#define rwlock_destroy(A) pthread_rwlock_destroy(A) #define rwlock_destroy(A) pthread_rwlock_destroy(A)
#elif defined(HAVE_RWLOCK_INIT) #elif defined(HAVE_RWLOCK_INIT)
......
...@@ -299,11 +299,15 @@ TODO list: ...@@ -299,11 +299,15 @@ TODO list:
pthread_mutex_lock(M);} pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\ #define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
(ulong)(M))); pthread_mutex_unlock(M);} (ulong)(M))); pthread_mutex_unlock(M);}
#define SEM_LOCK(M) { int val = 0; sem_getvalue (M, &val); \ #define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \
DBUG_PRINT("lock", ("sem lock 0x%lx (%d)", (ulong)(M), val)); \ if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")) \
sem_wait(M); DBUG_PRINT("lock", ("sem lock ok")); } else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
#define SEM_UNLOCK(M) {DBUG_PRINT("info", ("sem unlock 0x%lx", (ulong)(M))); \ #define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock 0x%lx", (ulong)(M))); \
sem_post(M); DBUG_PRINT("info", ("sem unlock ok")); } if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")) \
else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
#define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \
if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")) \
else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); }
#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \ #define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));} pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
#define STRUCT_UNLOCK(M) { \ #define STRUCT_UNLOCK(M) { \
...@@ -326,8 +330,9 @@ TODO list: ...@@ -326,8 +330,9 @@ TODO list:
#else #else
#define MUTEX_LOCK(M) pthread_mutex_lock(M) #define MUTEX_LOCK(M) pthread_mutex_lock(M)
#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M) #define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
#define SEM_LOCK(M) sem_wait(M) #define RW_WLOCK(M) rw_wrlock(M)
#define SEM_UNLOCK(M) sem_post(M) #define RW_RLOCK(M) rw_rdlock(M)
#define RW_UNLOCK(M) rw_unlock(M)
#define STRUCT_LOCK(M) pthread_mutex_lock(M) #define STRUCT_LOCK(M) pthread_mutex_lock(M)
#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M) #define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
#define BLOCK_LOCK_WR(B) B->query()->lock_writing() #define BLOCK_LOCK_WR(B) B->query()->lock_writing()
...@@ -445,9 +450,7 @@ void Query_cache_query::init_n_lock() ...@@ -445,9 +450,7 @@ void Query_cache_query::init_n_lock()
{ {
DBUG_ENTER("Query_cache_query::init_n_lock"); DBUG_ENTER("Query_cache_query::init_n_lock");
res=0; wri = 0; len = 0; res=0; wri = 0; len = 0;
sem_init(&lock, 0, 1); my_rwlock_init(&lock, NULL);
pthread_mutex_init(&clients_guard,MY_MUTEX_INIT_FAST);
clients = 0;
lock_writing(); lock_writing();
DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx", DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx",
((byte*) this)-ALIGN_SIZE(sizeof(Query_cache_block)))); ((byte*) this)-ALIGN_SIZE(sizeof(Query_cache_block))));
...@@ -465,8 +468,7 @@ void Query_cache_query::unlock_n_destroy() ...@@ -465,8 +468,7 @@ void Query_cache_query::unlock_n_destroy()
active semaphore active semaphore
*/ */
this->unlock_writing(); this->unlock_writing();
sem_destroy(&lock); rwlock_destroy(&lock);
pthread_mutex_destroy(&clients_guard);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -479,9 +481,9 @@ void Query_cache_query::unlock_n_destroy() ...@@ -479,9 +481,9 @@ void Query_cache_query::unlock_n_destroy()
Lock for read prevents only locking for write. Lock for read prevents only locking for write.
*/ */
void Query_cache_query::lock_writing() inline void Query_cache_query::lock_writing()
{ {
SEM_LOCK(&lock); RW_WLOCK(&lock);
} }
...@@ -495,41 +497,31 @@ void Query_cache_query::lock_writing() ...@@ -495,41 +497,31 @@ void Query_cache_query::lock_writing()
my_bool Query_cache_query::try_lock_writing() my_bool Query_cache_query::try_lock_writing()
{ {
DBUG_ENTER("Query_cache_block::try_lock_writing"); DBUG_ENTER("Query_cache_block::try_lock_writing");
if (sem_trywait(&lock)!=0 || clients != 0) if (rw_trywrlock(&lock)!=0)
{ {
DBUG_PRINT("info", ("can't lock semaphore")); DBUG_PRINT("info", ("can't lock rwlock"));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
DBUG_PRINT("info", ("mutex 'lock' 0x%lx locked", (ulong) &lock)); DBUG_PRINT("info", ("rwlock 0x%lx locked", (ulong) &lock));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
void Query_cache_query::lock_reading() inline void Query_cache_query::lock_reading()
{ {
MUTEX_LOCK(&clients_guard); RW_RLOCK(&lock);
if (++clients == 1)
SEM_LOCK(&lock);
MUTEX_UNLOCK(&clients_guard);
} }
void Query_cache_query::unlock_writing() inline void Query_cache_query::unlock_writing()
{ {
SEM_UNLOCK(&lock); RW_UNLOCK(&lock);
} }
void Query_cache_query::unlock_reading() inline void Query_cache_query::unlock_reading()
{ {
/* RW_UNLOCK(&lock);
To avoid unlocking semaphore before unlocking mutex (that may cause
destroying locked mutex), we use temporary boolean variable 'unlock'.
*/
MUTEX_LOCK(&clients_guard);
bool ulock = ((--clients) == 0);
MUTEX_UNLOCK(&clients_guard);
if (ulock) SEM_UNLOCK(&lock);
} }
extern "C" extern "C"
...@@ -2339,7 +2331,7 @@ Query_cache::double_linked_list_simple_include(Query_cache_block *point, ...@@ -2339,7 +2331,7 @@ Query_cache::double_linked_list_simple_include(Query_cache_block *point,
*list_pointer=point->next=point->prev=point; *list_pointer=point->next=point->prev=point;
else else
{ {
// insert to and of list // insert to the end of list
point->next = (*list_pointer); point->next = (*list_pointer);
point->prev = (*list_pointer)->prev; point->prev = (*list_pointer)->prev;
point->prev->next = point; point->prev->next = point;
...@@ -2634,8 +2626,7 @@ my_bool Query_cache::move_by_type(byte **border, ...@@ -2634,8 +2626,7 @@ my_bool Query_cache::move_by_type(byte **border,
} while ( result_block != first_result_block ); } while ( result_block != first_result_block );
} }
Query_cache_query *new_query= ((Query_cache_query *) new_block->data()); Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
sem_init(&new_query->lock, 0, 1); my_rwlock_init(&new_query->lock, NULL);
pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST);
/* /*
If someone is writing to this block, inform the writer that the block If someone is writing to this block, inform the writer that the block
......
...@@ -63,8 +63,6 @@ ...@@ -63,8 +63,6 @@
#define TABLE_COUNTER_TYPE uint8 #define TABLE_COUNTER_TYPE uint8
#include <my_semaphore.h>
struct Query_cache_block; struct Query_cache_block;
struct Query_cache_block_table; struct Query_cache_block_table;
struct Query_cache_table; struct Query_cache_table;
...@@ -110,16 +108,13 @@ struct Query_cache_block ...@@ -110,16 +108,13 @@ struct Query_cache_block
inline Query_cache_block_table *table(TABLE_COUNTER_TYPE n); inline Query_cache_block_table *table(TABLE_COUNTER_TYPE n);
}; };
struct Query_cache_query struct Query_cache_query
{ {
ulonglong limit_found_rows; ulonglong limit_found_rows;
rw_lock_t lock;
Query_cache_block *res; Query_cache_block *res;
NET *wri; NET *wri;
ulong len; ulong len;
sem_t lock; // R/W lock of block
pthread_mutex_t clients_guard;
uint clients;
inline void init_n_lock(); inline void init_n_lock();
void unlock_n_destroy(); void unlock_n_destroy();
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
/* HANDLER ... commands - direct access to ISAM */ /* HANDLER ... commands - direct access to ISAM */
#include <assert.h>
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h" #include "sql_select.h"
#include <assert.h>
/* TODO: /* TODO:
HANDLER blabla OPEN [ AS foobar ] [ (column-list) ] HANDLER blabla OPEN [ AS foobar ] [ (column-list) ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment