summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2013-10-04 18:25:51 -0400
committerKeith Bostic <keith@wiredtiger.com>2013-10-04 18:25:51 -0400
commitf3f6976a411e3cfdc712e82aabb314bd89b9dc2c (patch)
treefc7ac05873fbde6c49a60fce296c277df9ec8a26
parent8a8a16ac6eb5a05a8f2c70abc314e6c4343e25d3 (diff)
parentd219e4f9e89cafa5d9a0c0b25f1ed3cb390b59df (diff)
downloadmongo-f3f6976a411e3cfdc712e82aabb314bd89b9dc2c.tar.gz
Merge branch 'develop' into mutex-cleanup
Conflicts: src/support/global.c
-rw-r--r--dist/s_string.ok8
-rw-r--r--src/include/cursor.i13
-rw-r--r--src/include/extern.h1
-rw-r--r--src/lsm/lsm_merge.c13
-rw-r--r--src/support/cksum.c109
-rw-r--r--src/support/global.c6
-rw-r--r--src/txn/txn_ckpt.c14
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);
}