Commit d2c6783c authored by Rich Prohaska's avatar Rich Prohaska

test lock overhead. addresses #1075

git-svn-id: file:///svn/tokudb@5830 c7de825b-a66e-492c-adef-691d508d4ae1
parent 5a9b210d
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#define DO_CACHETABLE_LOCK 0
//#define TRACE_CACHETABLE //#define TRACE_CACHETABLE
#ifdef TRACE_CACHETABLE #ifdef TRACE_CACHETABLE
...@@ -53,8 +56,27 @@ struct cachetable { ...@@ -53,8 +56,27 @@ struct cachetable {
long size_current, size_limit; long size_current, size_limit;
LSN lsn_of_checkpoint; // the most recent checkpoint in the log. LSN lsn_of_checkpoint; // the most recent checkpoint in the log.
TOKULOGGER logger; TOKULOGGER logger;
#if DO_CACHETABLE_LOCK
pthread_mutex_t mutex;
#endif
}; };
// lock the cachetable mutex
static inline void cachetable_lock(CACHETABLE ct __attribute__((unused))) {
#if DO_CACHETABLE_LOCK
int r = pthread_mutex_lock(&ct->mutex); assert(r == 0);
#endif
}
// unlock the cachetable mutex
static inline void cachetable_unlock(CACHETABLE ct __attribute__((unused))) {
#if DO_CACHETABLE_LOCK
int r = pthread_mutex_unlock(&ct->mutex); assert(r == 0);
#endif
}
struct fileid { struct fileid {
dev_t st_dev; /* device and inode are enough to uniquely identify a file in unix. */ dev_t st_dev; /* device and inode are enough to uniquely identify a file in unix. */
ino_t st_ino; ino_t st_ino;
...@@ -99,6 +121,9 @@ int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN initial_lsn, ...@@ -99,6 +121,9 @@ int toku_create_cachetable(CACHETABLE *result, long size_limit, LSN initial_lsn,
t->size_limit = size_limit; t->size_limit = size_limit;
t->lsn_of_checkpoint = initial_lsn; t->lsn_of_checkpoint = initial_lsn;
t->logger = logger; t->logger = logger;
#if DO_CACHTABLE_LOCK
int r = pthread_mutex_init(&t->mutex, 0); assert(r == 0);
#endif
*result = t; *result = t;
return 0; return 0;
} }
...@@ -515,6 +540,8 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v ...@@ -515,6 +540,8 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) { cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) {
WHEN_TRACE_CT(printf("%s:%d CT cachetable_put(%lld)=%p\n", __FILE__, __LINE__, key, value)); WHEN_TRACE_CT(printf("%s:%d CT cachetable_put(%lld)=%p\n", __FILE__, __LINE__, key, value));
int count=0; int count=0;
CACHETABLE ct = cachefile->cachetable;
cachetable_lock(ct);
{ {
PAIR p; PAIR p;
for (p=cachefile->cachetable->table[fullhash&(cachefile->cachetable->table_size-1)]; p; p=p->hash_chain) { for (p=cachefile->cachetable->table[fullhash&(cachefile->cachetable->table_size-1)]; p; p=p->hash_chain) {
...@@ -527,21 +554,27 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v ...@@ -527,21 +554,27 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v
assert(p->flush_callback==flush_callback); assert(p->flush_callback==flush_callback);
assert(p->fetch_callback==fetch_callback); assert(p->fetch_callback==fetch_callback);
p->pinned++; /* Already present. But increment the pin count. */ p->pinned++; /* Already present. But increment the pin count. */
cachetable_unlock(ct);
return -1; /* Already present. */ return -1; /* Already present. */
} }
} }
} }
int r; int r;
note_hash_count(count); note_hash_count(count);
if ((r=maybe_flush_some(cachefile->cachetable, size))) return r; if ((r=maybe_flush_some(cachefile->cachetable, size))) {
cachetable_unlock(ct);
return r;
}
// flushing could change the table size, but wont' change the fullhash // flushing could change the table size, but wont' change the fullhash
r = cachetable_insert_at(cachefile, fullhash, key, value, size, flush_callback, fetch_callback, extraargs, 1, ZERO_LSN); r = cachetable_insert_at(cachefile, fullhash, key, value, size, flush_callback, fetch_callback, extraargs, 1, ZERO_LSN);
cachetable_unlock(ct);
return r; return r;
} }
int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, void**value, long *sizep, int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, void**value, long *sizep,
cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) { cachetable_flush_func_t flush_callback, cachetable_fetch_func_t fetch_callback, void *extraargs) {
CACHETABLE t = cachefile->cachetable; CACHETABLE t = cachefile->cachetable;
cachetable_lock(t);
int tsize __attribute__((__unused__)) = t->table_size; int tsize __attribute__((__unused__)) = t->table_size;
PAIR p; PAIR p;
int count=0; int count=0;
...@@ -553,6 +586,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful ...@@ -553,6 +586,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful
if (sizep) *sizep = p->size; if (sizep) *sizep = p->size;
p->pinned++; p->pinned++;
lru_touch(t,p); lru_touch(t,p);
cachetable_unlock(t);
WHEN_TRACE_CT(printf("%s:%d cachtable_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value)); WHEN_TRACE_CT(printf("%s:%d cachtable_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value));
return 0; return 0;
} }
...@@ -566,6 +600,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful ...@@ -566,6 +600,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful
LSN written_lsn; LSN written_lsn;
WHEN_TRACE_CT(printf("%s:%d CT: fetch_callback(%lld...)\n", __FILE__, __LINE__, key)); WHEN_TRACE_CT(printf("%s:%d CT: fetch_callback(%lld...)\n", __FILE__, __LINE__, key));
if ((r=fetch_callback(cachefile, key, fullhash, &toku_value, &size, extraargs, &written_lsn))) { if ((r=fetch_callback(cachefile, key, fullhash, &toku_value, &size, extraargs, &written_lsn))) {
cachetable_unlock(t);
return r; return r;
} }
cachetable_insert_at(cachefile, fullhash, key, toku_value, size, flush_callback, fetch_callback, extraargs, 0, written_lsn); cachetable_insert_at(cachefile, fullhash, key, toku_value, size, flush_callback, fetch_callback, extraargs, 0, written_lsn);
...@@ -574,7 +609,11 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful ...@@ -574,7 +609,11 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful
*sizep = size; *sizep = size;
// maybe_flush_some(t, size); // maybe_flush_some(t, size);
} }
if ((r=maybe_flush_some(t, 0))) return r; if ((r=maybe_flush_some(t, 0))) {
cachetable_unlock(t);
return r;
}
cachetable_unlock(t);
WHEN_TRACE_CT(printf("%s:%d did fetch: cachtable_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value)); WHEN_TRACE_CT(printf("%s:%d did fetch: cachtable_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value));
return 0; return 0;
} }
...@@ -583,6 +622,7 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3 ...@@ -583,6 +622,7 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3
CACHETABLE t = cachefile->cachetable; CACHETABLE t = cachefile->cachetable;
PAIR p; PAIR p;
int count = 0; int count = 0;
cachetable_lock(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; count++;
if (p->key==key && p->cachefile==cachefile) { if (p->key==key && p->cachefile==cachefile) {
...@@ -590,10 +630,12 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3 ...@@ -590,10 +630,12 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3
*value = p->value; *value = p->value;
p->pinned++; p->pinned++;
lru_touch(t,p); lru_touch(t,p);
cachetable_unlock(t);
//printf("%s:%d cachetable_maybe_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value); //printf("%s:%d cachetable_maybe_get_and_pin(%lld)--> %p\n", __FILE__, __LINE__, key, *value);
return 0; return 0;
} }
} }
cachetable_unlock(t);
note_hash_count(count); note_hash_count(count);
return -1; return -1;
} }
...@@ -606,6 +648,7 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, ...@@ -606,6 +648,7 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash,
//printf("%s:%d is dirty now=%d\n", __FILE__, __LINE__, dirty); //printf("%s:%d is dirty now=%d\n", __FILE__, __LINE__, dirty);
int count = 0; int count = 0;
//assert(fullhash == toku_cachetable_hash(cachefile, key)); //assert(fullhash == toku_cachetable_hash(cachefile, key));
cachetable_lock(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; count++;
if (p->key==key && p->cachefile==cachefile) { if (p->key==key && p->cachefile==cachefile) {
...@@ -621,11 +664,15 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, ...@@ -621,11 +664,15 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash,
WHEN_TRACE_CT(printf("[count=%lld]\n", p->pinned)); WHEN_TRACE_CT(printf("[count=%lld]\n", p->pinned));
{ {
int r; int r;
if ((r=maybe_flush_some(t, 0))) return r; if ((r=maybe_flush_some(t, 0))) {
cachetable_unlock(t); return r;
} }
}
cachetable_unlock(t);
return 0; return 0;
} }
} }
cachetable_unlock(t);
note_hash_count(count); note_hash_count(count);
return -1; return -1;
} }
...@@ -768,6 +815,9 @@ int toku_cachetable_close (CACHETABLE *tp) { ...@@ -768,6 +815,9 @@ int toku_cachetable_close (CACHETABLE *tp) {
for (i=0; i<t->table_size; i++) { for (i=0; i<t->table_size; i++) {
if (t->table[i]) return -1; if (t->table[i]) return -1;
} }
#if DO_CACHETABLE_LOCK
r = pthread_mutex_destroy(&t->mutex); assert(r == 0);
#endif
toku_free(t->table); toku_free(t->table);
toku_free(t); toku_free(t);
*tp = 0; *tp = 0;
......
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