diff options
author | Keith Bostic <keith@wiredtiger.com> | 2013-10-04 18:25:51 -0400 |
---|---|---|
committer | Keith Bostic <keith@wiredtiger.com> | 2013-10-04 18:25:51 -0400 |
commit | f3f6976a411e3cfdc712e82aabb314bd89b9dc2c (patch) | |
tree | fc7ac05873fbde6c49a60fce296c277df9ec8a26 | |
parent | 8a8a16ac6eb5a05a8f2c70abc314e6c4343e25d3 (diff) | |
parent | d219e4f9e89cafa5d9a0c0b25f1ed3cb390b59df (diff) | |
download | mongo-f3f6976a411e3cfdc712e82aabb314bd89b9dc2c.tar.gz |
Merge branch 'develop' into mutex-cleanup
Conflicts:
src/support/global.c
-rw-r--r-- | dist/s_string.ok | 8 | ||||
-rw-r--r-- | src/include/cursor.i | 13 | ||||
-rw-r--r-- | src/include/extern.h | 1 | ||||
-rw-r--r-- | src/lsm/lsm_merge.c | 13 | ||||
-rw-r--r-- | src/support/cksum.c | 109 | ||||
-rw-r--r-- | src/support/global.c | 6 | ||||
-rw-r--r-- | src/txn/txn_ckpt.c | 14 |
7 files changed, 134 insertions, 30 deletions
diff --git a/dist/s_string.ok b/dist/s_string.ok index eb7d56a69ff..6edde9baa1a 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -48,7 +48,9 @@ CMP COL's CONCAT CONFIG +CPUID CPUs +CRC CURSORs CURSTD CallsCustDate @@ -275,6 +277,7 @@ alfred alloc allocator allocsize +amd ao ap api @@ -357,6 +360,7 @@ const copyin copyout cp +cpuid crc cref ctime @@ -497,6 +501,7 @@ hrow html huffman hval +hw iS iSh icount @@ -508,6 +513,7 @@ incr incrementing incrv indices +indirects indx infeasible init @@ -773,6 +779,7 @@ subtree subtrees sunique superset +sw sys syserr sz @@ -888,6 +895,7 @@ wrlock ws wti wts +xF xff xxxx xxxxx diff --git a/src/include/cursor.i b/src/include/cursor.i index 32322ec6fdc..95af9be2275 100644 --- a/src/include/cursor.i +++ b/src/include/cursor.i @@ -196,9 +196,8 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd) goto slow; __wt_cell_unpack((WT_CELL *)ikey, unpack); if (unpack->type == WT_CELL_KEY && unpack->prefix == 0) { - kb->data = cbt->tmp.data = unpack->data; - kb->size = cbt->tmp.size = unpack->size; - cbt->rip_saved = rip; + cbt->tmp.data = unpack->data; + cbt->tmp.size = unpack->size; } else if (unpack->type == WT_CELL_KEY && cbt->rip_saved != NULL && cbt->rip_saved == rip - 1) { /* @@ -222,17 +221,17 @@ __cursor_row_slot_return(WT_CURSOR_BTREE *cbt, WT_ROW *rip, WT_UPDATE *upd) memcpy((uint8_t *)cbt->tmp.data + unpack->prefix, unpack->data, unpack->size); cbt->tmp.size = unpack->prefix + unpack->size; - kb->data = cbt->tmp.data; - kb->size = cbt->tmp.size; - cbt->rip_saved = rip; } else { /* * __wt_row_leaf_key_work instead of __wt_row_leaf_key: * we do __wt_row_leaf_key's fast-path checks inline. */ slow: WT_RET(__wt_row_leaf_key_work( - session, cbt->page, rip, kb, 0)); + session, cbt->page, rip, &cbt->tmp, 0)); } + kb->data = cbt->tmp.data; + kb->size = cbt->tmp.size; + cbt->rip_saved = rip; } /* diff --git a/src/include/extern.h b/src/include/extern.h index 1ef100c6ef9..d4abcf3615b 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -1169,6 +1169,7 @@ extern int __wt_session_discard_btree( WT_SESSION_IMPL *session, WT_DATA_HANDLE_CACHE *dhandle_cache); extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]); extern uint32_t __wt_cksum(const void *chunk, size_t len); +extern void __wt_cksum_init(); extern void __wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler); extern void __wt_err(WT_SESSION_IMPL *session, diff --git a/src/lsm/lsm_merge.c b/src/lsm/lsm_merge.c index f28ac307994..5407f9cd57f 100644 --- a/src/lsm/lsm_merge.c +++ b/src/lsm/lsm_merge.c @@ -207,8 +207,8 @@ __wt_lsm_merge( F_SET(src, WT_CURSTD_RAW); WT_ERR(__wt_clsm_init_merge(src, start_chunk, start_id, nchunks)); - WT_WITH_SCHEMA_LOCK(session, ret = __wt_lsm_tree_setup_chunk( - session, lsm_tree, chunk)); + WT_WITH_SCHEMA_LOCK(session, + ret = __wt_lsm_tree_setup_chunk(session, lsm_tree, chunk)); WT_ERR(ret); if (create_bloom) { WT_CLEAR(buf); @@ -232,10 +232,9 @@ __wt_lsm_merge( for (insert_count = 0; (ret = src->next(src)) == 0; insert_count++) { if (insert_count % 1000 && - !F_ISSET(lsm_tree, WT_LSM_TREE_WORKING)) { - ret = EINTR; - goto err; - } + !F_ISSET(lsm_tree, WT_LSM_TREE_WORKING)) + WT_ERR(EINTR); + WT_ERR(src->get_key(src, &key)); dest->set_key(dest, &key); WT_ERR(src->get_value(src, &value)); @@ -284,7 +283,7 @@ __wt_lsm_merge( /* * Open a handle on the new chunk before application threads attempt - * to access it. Opening the pre-loads internal pages into the file + * to access it, opening it pre-loads internal pages into the file * system cache. */ cfg[1] = "checkpoint=WiredTigerCheckpoint"; diff --git a/src/support/cksum.c b/src/support/cksum.c index 7e9befeb2fa..383b899b9ab 100644 --- a/src/support/cksum.c +++ b/src/support/cksum.c @@ -27,6 +27,20 @@ #include "wt_internal.h" +/* + * This file contains two implementations for computing CRC: one that uses + * hardware CRC instructions, available on newer x86_64/amd64, and one that uses + * a fast software algorithm. __wt_cksum() provides a common entry point that + * indirects to one of these two methods. + */ +static uint32_t __wt_cksum_sw(const void *chunk, size_t len); +static uint32_t __wt_cksum_hw(const void *chunk, size_t len); + +static uint32_t (*__wt_cksum_func)(const void *chunk, size_t len); + +/* + * The CRC slicing tables are used by __wt_cksum_sw. + */ static const uint32_t g_crc_slicing[8][256] = { #ifdef WORDS_BIGENDIAN /* @@ -1080,8 +1094,8 @@ static const uint32_t g_crc_slicing[8][256] = { }; /* - * __wt_cksum -- - * Return a checksum for a chunk of memory. + * __wt_cksum_sw -- + * Return a checksum for a chunk of memory, computed in software. * * Slicing-by-8 algorithm by Michael E. Kounavis and Frank L. Berry from * Intel Corp.: @@ -1094,8 +1108,8 @@ static const uint32_t g_crc_slicing[8][256] = { * value of the crc is byte reversed from what it would be at that step for * little endian. */ -uint32_t -__wt_cksum(const void *chunk, size_t len) +static uint32_t +__wt_cksum_sw(const void *chunk, size_t len) { uint32_t crc, next; size_t nqwords; @@ -1158,3 +1172,90 @@ __wt_cksum(const void *chunk, size_t len) #endif return (~crc); } + +#if (defined(__amd64) || defined(__x86_64)) +/* + * __wt_cksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_cksum_hw(const void *chunk, size_t len) +{ + uint32_t crc; + size_t nqwords; + const uint8_t *p; + const uint64_t *p64; + + crc = 0xffffffff; + + /* Checksum one byte at a time to the first 4B boundary. */ + for (p = chunk; + ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && + len > 0; ++p, --len) { + __asm__ __volatile__( + ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" + : "=S" (crc) + : "0" (crc), "c" (*p)); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + __asm__ __volatile__ ( + ".byte 0xF2, 0x48, 0x0F, 0x38, 0xF1, 0xF1" + : "=S"(crc) + : "0"(crc), "c" (*p64)); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + __asm__ __volatile__( + ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" + : "=S" (crc) + : "0" (crc), "c" (*p)); + } + return (~crc); +} +#endif + +/* + * __wt_cksum -- + * Return a checksum for a chunk of memory + * using the fastest method available. + */ +uint32_t +__wt_cksum(const void *chunk, size_t len) +{ + return (*__wt_cksum_func)(chunk, len); +} + +/* + * __wt_cksum_init -- + * Detect CRC hardware if possible, and return one of + * CRC_HARDWARE_PRESENT or CRC_HARDWARE_ABSENT. + */ +void +__wt_cksum_init() +{ +#if (defined(__amd64) || defined(__x86_64)) + unsigned int eax, ebx, ecx, edx; + + __asm__ __volatile__ ( + "cpuid" + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "a" (1)); + +#define CPUID_ECX_HAS_SSE42 (1 << 20) + + if (ecx & CPUID_ECX_HAS_SSE42) + __wt_cksum_func = __wt_cksum_hw; + else + __wt_cksum_func = __wt_cksum_sw; + +#else + __wt_cksum_func = __wt_cksum_sw; +#endif +} diff --git a/src/support/global.c b/src/support/global.c index c5e96f87050..b06ccad5ce1 100644 --- a/src/support/global.c +++ b/src/support/global.c @@ -33,8 +33,12 @@ __wt_pthread_once(void) { WT_DECL_RET; - if ((ret = __wt_spin_init(NULL, &__wt_process.spinlock)) != 0) + if ((ret = __wt_spin_init(NULL, &__wt_process.spinlock)) != 0) { __wt_pthread_once_failed = ret; + return; + } + + __wt_cksum_init(); TAILQ_INIT(&__wt_process.connqh); diff --git a/src/txn/txn_ckpt.c b/src/txn/txn_ckpt.c index 5eeeb59cffc..058d41faf58 100644 --- a/src/txn/txn_ckpt.c +++ b/src/txn/txn_ckpt.c @@ -252,7 +252,7 @@ __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) * to open one. We are holding other handle locks, it is not safe to * lock conn->spinlock. */ - txn->isolation = TXN_ISO_READ_UNCOMMITTED; + session->isolation = txn->isolation = TXN_ISO_READ_UNCOMMITTED; saved_meta_next = session->meta_track_next; session->meta_track_next = NULL; WT_WITH_DHANDLE(session, dhandle, ret = __wt_checkpoint(session, cfg)); @@ -281,7 +281,7 @@ err: /* __wt_spin_unlock(session, &conn->checkpoint_lock); __wt_scr_free(&tmp); - session->isolation = txn->isolation = saved_isolation; + session->isolation = saved_isolation; return (ret); } @@ -413,8 +413,6 @@ __checkpoint_worker( WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle; WT_DECL_RET; - WT_TXN *txn; - WT_TXN_ISOLATION saved_isolation; const char *name; int deleted, force, hot_backup_locked, track_ckpt; char *name_alloc; @@ -422,13 +420,11 @@ __checkpoint_worker( btree = S2BT(session); conn = S2C(session); dhandle = session->dhandle; - txn = &session->txn; bm = btree->bm; ckpt = ckptbase = NULL; hot_backup_locked = 0; name_alloc = NULL; - saved_isolation = session->isolation; track_ckpt = 1; /* @@ -723,10 +719,8 @@ __checkpoint_worker( /* Flush the file from the cache, creating the checkpoint. */ if (is_checkpoint) WT_ERR(__wt_bt_cache_op(session, ckptbase, WT_SYNC_CHECKPOINT)); - else { - session->isolation = txn->isolation = TXN_ISO_READ_UNCOMMITTED; + else WT_ERR(__wt_bt_cache_op(session, ckptbase, WT_SYNC_DISCARD)); - } /* * All blocks being written have been written; set the object's write @@ -737,7 +731,6 @@ __checkpoint_worker( ckpt->write_gen = btree->write_gen; fake: /* Update the object's metadata. */ - session->isolation = txn->isolation = TXN_ISO_READ_UNCOMMITTED; ret = __wt_meta_ckptlist_set(session, dhandle->name, ckptbase); WT_ERR(ret); @@ -759,7 +752,6 @@ err: if (hot_backup_locked) __wt_spin_unlock(session, &conn->hot_backup_lock); skip: __wt_meta_ckptlist_free(session, ckptbase); __wt_free(session, name_alloc); - session->isolation = txn->isolation = saved_isolation; return (ret); } |