diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2016-09-08 02:46:05 -0400 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2016-09-08 16:46:05 +1000 |
commit | 881a37eea1668d47c5d5fb38001a2850ca117495 (patch) | |
tree | 898db838171a0920fc0b29ac900ecdcf7ec6ee6a | |
parent | 5f07ab685f2b1e978cfda354dd52a5fc52f8f8ab (diff) | |
download | mongo-881a37eea1668d47c5d5fb38001a2850ca117495.tar.gz |
WT-2873 Refactor CRC32 code (#3000)
* Add --enable-crc32-hardware configuration option (configured on by default), which allows CRC32 hardware support to be turned off.
* Move the CRC32 implementation in software from the x86-specific code to software/checksum.c, leave the x86-specific code in x86/crc32-x86.c.
* Move the pointer to the checksum function from a file static to the WT_PROCESS.cksum field, change the __wt_cksum_init() function to set that field.
* WT-2882 Create CRC32 Hardware implementation for ARM8
* Change "cksum" to "checksum" everywhere (hopefully) no semantic changes.
38 files changed, 509 insertions, 383 deletions
diff --git a/SConstruct b/SConstruct index c985800d13c..0ccdf59babc 100644 --- a/SConstruct +++ b/SConstruct @@ -245,6 +245,7 @@ wtheader = env.Substfile( # included. # condition_map = { + 'ARM64_HOST' : False, 'POSIX_HOST' : env['PLATFORM'] == 'posix', 'POWERPC_HOST' : False, 'WINDOWS_HOST' : env['PLATFORM'] == 'win32', diff --git a/build_posix/aclocal/options.m4 b/build_posix/aclocal/options.m4 index 5f9b8748df2..1f6a1690279 100644 --- a/build_posix/aclocal/options.m4 +++ b/build_posix/aclocal/options.m4 @@ -47,6 +47,19 @@ AM_CONDITIONAL([HAVE_BUILTIN_EXTENSION_ZLIB], [test "$wt_cv_with_builtin_extension_zlib" = "yes"]) AC_MSG_RESULT($with_builtins) +AH_TEMPLATE( + HAVE_CRC32_HARDWARE, [Define to 1 to configure CRC32 hardware support.]) +AC_MSG_CHECKING(if --enable-crc32-hardware option specified) +AC_ARG_ENABLE(crc32-hardware, + AC_HELP_STRING([--enable-crc32-hardware], + [Enable CRC32 hardware support.]), r=$enableval, r=yes) +case "$r" in +no) wt_cv_enable_crc32_hardware=no;; +*) AC_DEFINE(HAVE_CRC32_HARDWARE) + wt_cv_enable_crc32_hardware=yes;; +esac +AC_MSG_RESULT($wt_cv_enable_crc32_hardware) + AH_TEMPLATE(HAVE_DIAGNOSTIC, [Define to 1 for diagnostic tests.]) AC_MSG_CHECKING(if --enable-diagnostic option specified) AC_ARG_ENABLE(diagnostic, diff --git a/build_posix/configure.ac.in b/build_posix/configure.ac.in index 00aa0bc9f95..cbd9e4e4123 100644 --- a/build_posix/configure.ac.in +++ b/build_posix/configure.ac.in @@ -65,6 +65,10 @@ AS_CASE([$host_cpu], [s390x*], [wt_cv_zseries="yes"], [wt_cv_zseries="no"]) AM_CONDITIONAL([ZSERIES_HOST], [test "$wt_cv_zseries" = "yes"]) +AS_CASE([$host_cpu], + [aarch64*], [wt_cv_arm64="yes"], + [wt_cv_arm64="no"]) +AM_CONDITIONAL([ARM64_HOST], [test "$wt_cv_arm64" = "yes"]) # This is a workaround as part of WT-2459. Currently, clang (v3.7) does not # support compiling the ASM code we have to perform the CRC checks on PowerPC. diff --git a/build_win/wiredtiger_config.h b/build_win/wiredtiger_config.h index ad82b13f8a8..83ddc6eb194 100644 --- a/build_win/wiredtiger_config.h +++ b/build_win/wiredtiger_config.h @@ -22,6 +22,9 @@ /* Define to 1 if you have the `clock_gettime' function. */ /* #undef HAVE_CLOCK_GETTIME */ +/* Define to 1 to enable CRC32 hardware support. */ +/* #undef HAVE_CRC32_HARDWARE */ + /* Define to 1 for diagnostic tests. */ /* #undef HAVE_DIAGNOSTIC */ diff --git a/dist/filelist b/dist/filelist index e16ae879a33..19fa1122a27 100644 --- a/dist/filelist +++ b/dist/filelist @@ -47,9 +47,11 @@ src/btree/row_key.c src/btree/row_modify.c src/btree/row_srch.c src/cache/cache_las.c +src/checksum/arm64/crc32-arm64.c ARM64_HOST src/checksum/power8/crc32.S POWERPC_HOST src/checksum/power8/crc32_wrapper.c POWERPC_HOST -src/checksum/x86/checksum.c X86_HOST +src/checksum/software/checksum.c +src/checksum/x86/crc32-x86.c X86_HOST src/checksum/zseries/crc32-s390x.c ZSERIES_HOST src/checksum/zseries/crc32le-vx.S ZSERIES_HOST src/config/config.c diff --git a/dist/s_prototypes b/dist/s_prototypes index a2fe76ffa9b..5633c3b5140 100755 --- a/dist/s_prototypes +++ b/dist/s_prototypes @@ -76,6 +76,7 @@ externs f=../src/include/extern.h l=`sed \ -e '/^[a-z]/!d' \ + -e '/\/checksum\/arm64/d' \ -e '/\/checksum\/power8/d' \ -e '/\/checksum\/zseries/d' \ -e '/os_posix/d' \ diff --git a/dist/s_string.ok b/dist/s_string.ok index 71dd10bd100..1887cbd936f 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -473,6 +473,7 @@ call's calloc cas catfmt +cb ccr cd centric @@ -551,6 +552,7 @@ curtable cust customp cv +cx cxa dT data's diff --git a/examples/c/ex_encrypt.c b/examples/c/ex_encrypt.c index 3b3323bc091..5d5cc66c87f 100644 --- a/examples/c/ex_encrypt.c +++ b/examples/c/ex_encrypt.c @@ -76,12 +76,12 @@ typedef struct { #define IV_LEN 16 /* - * make_cksum -- + * make_checksum -- * This is where one would call a checksum function on the encrypted * buffer. Here we just put a constant value in it. */ static void -make_cksum(uint8_t *dst) +make_checksum(uint8_t *dst) { int i; /* @@ -220,7 +220,7 @@ rotate_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * Checksum the encrypted buffer and add the IV. */ i = 0; - make_cksum(&dst[i]); + make_checksum(&dst[i]); i += CHKSUM_LEN; make_iv(&dst[i]); *result_lenp = dst_len; diff --git a/ext/encryptors/rotn/rotn_encrypt.c b/ext/encryptors/rotn/rotn_encrypt.c index 3b5379ca410..4d614e2e409 100644 --- a/ext/encryptors/rotn/rotn_encrypt.c +++ b/ext/encryptors/rotn/rotn_encrypt.c @@ -101,12 +101,12 @@ rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, } /* - * make_cksum -- + * make_checksum -- * This is where one would call a checksum function on the encrypted * buffer. Here we just put a constant value in it. */ static void -make_cksum(uint8_t *dst) +make_checksum(uint8_t *dst) { int i; /* @@ -212,7 +212,7 @@ rotn_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * Checksum the encrypted buffer and add the IV. */ i = 0; - make_cksum(&dst[i]); + make_checksum(&dst[i]); i += CHKSUM_LEN; make_iv(&dst[i]); *result_lenp = dst_len; diff --git a/src/block/block_addr.c b/src/block/block_addr.c index d8cc1d627cf..dadd17de4a6 100644 --- a/src/block/block_addr.c +++ b/src/block/block_addr.c @@ -15,7 +15,7 @@ */ static int __block_buffer_to_addr(uint32_t allocsize, - const uint8_t **pp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump) + const uint8_t **pp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) { uint64_t o, s, c; @@ -37,11 +37,11 @@ __block_buffer_to_addr(uint32_t allocsize, */ if (s == 0) { *offsetp = 0; - *sizep = *cksump = 0; + *sizep = *checksump = 0; } else { *offsetp = (wt_off_t)(o + 1) * allocsize; *sizep = (uint32_t)s * allocsize; - *cksump = (uint32_t)c; + *checksump = (uint32_t)c; } return (0); } @@ -52,7 +52,7 @@ __block_buffer_to_addr(uint32_t allocsize, */ int __wt_block_addr_to_buffer(WT_BLOCK *block, - uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t cksum) + uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t checksum) { uint64_t o, s, c; @@ -63,7 +63,7 @@ __wt_block_addr_to_buffer(WT_BLOCK *block, } else { o = (uint64_t)offset / block->allocsize - 1; s = size / block->allocsize; - c = cksum; + c = checksum; } WT_RET(__wt_vpack_uint(pp, 0, o)); WT_RET(__wt_vpack_uint(pp, 0, s)); @@ -78,10 +78,10 @@ __wt_block_addr_to_buffer(WT_BLOCK *block, */ int __wt_block_buffer_to_addr(WT_BLOCK *block, - const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump) + const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) { return (__block_buffer_to_addr( - block->allocsize, &p, offsetp, sizep, cksump)); + block->allocsize, &p, offsetp, sizep, checksump)); } /* @@ -93,14 +93,15 @@ __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(session); WT_UNUSED(addr_size); WT_UNUSED(live); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); #ifdef HAVE_DIAGNOSTIC /* @@ -124,17 +125,18 @@ __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* Printable representation. */ WT_RET(__wt_buf_fmt(session, buf, "[%" PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", - (uintmax_t)offset, (uintmax_t)offset + size, size, cksum)); + (uintmax_t)offset, (uintmax_t)offset + size, size, checksum)); return (0); } @@ -156,13 +158,13 @@ __block_buffer_to_ckpt(WT_SESSION_IMPL *session, pp = &p; WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->root_offset, &ci->root_size, &ci->root_cksum)); + &ci->root_offset, &ci->root_size, &ci->root_checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->alloc.offset, &ci->alloc.size, &ci->alloc.cksum)); + &ci->alloc.offset, &ci->alloc.size, &ci->alloc.checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->avail.offset, &ci->avail.size, &ci->avail.cksum)); + &ci->avail.offset, &ci->avail.size, &ci->avail.checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->discard.offset, &ci->discard.size, &ci->discard.cksum)); + &ci->discard.offset, &ci->discard.size, &ci->discard.checksum)); WT_RET(__wt_vunpack_uint(pp, 0, &a)); ci->file_size = (wt_off_t)a; WT_RET(__wt_vunpack_uint(pp, 0, &a)); @@ -214,13 +216,13 @@ __wt_block_ckpt_to_buffer(WT_SESSION_IMPL *session, (*pp)++; WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->root_offset, ci->root_size, ci->root_cksum)); + ci->root_offset, ci->root_size, ci->root_checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->alloc.offset, ci->alloc.size, ci->alloc.cksum)); + ci->alloc.offset, ci->alloc.size, ci->alloc.checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->avail.offset, ci->avail.size, ci->avail.cksum)); + ci->avail.offset, ci->avail.size, ci->avail.checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->discard.offset, ci->discard.size, ci->discard.cksum)); + ci->discard.offset, ci->discard.size, ci->discard.checksum)); a = (uint64_t)ci->file_size; WT_RET(__wt_vpack_uint(pp, 0, a)); a = (uint64_t)ci->ckpt_size; diff --git a/src/block/block_ckpt.c b/src/block/block_ckpt.c index 22ee4376d29..b7ac953cdb1 100644 --- a/src/block/block_ckpt.c +++ b/src/block/block_ckpt.c @@ -117,7 +117,7 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, if (ci->root_offset != WT_BLOCK_INVALID_OFFSET) { endp = root_addr; WT_ERR(__wt_block_addr_to_buffer(block, &endp, - ci->root_offset, ci->root_size, ci->root_cksum)); + ci->root_offset, ci->root_size, ci->root_checksum)); *root_addr_sizep = WT_PTRDIFF(endp, root_addr); } @@ -216,7 +216,7 @@ __wt_block_ckpt_destroy(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci) */ int __wt_block_checkpoint(WT_SESSION_IMPL *session, - WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) + WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { WT_BLOCK_CKPT *ci; WT_DECL_RET; @@ -237,11 +237,11 @@ __wt_block_checkpoint(WT_SESSION_IMPL *session, */ if (buf == NULL) { ci->root_offset = WT_BLOCK_INVALID_OFFSET; - ci->root_size = ci->root_cksum = 0; + ci->root_size = ci->root_checksum = 0; } else WT_ERR(__wt_block_write_off(session, block, buf, - &ci->root_offset, &ci->root_size, &ci->root_cksum, - data_cksum, true, false)); + &ci->root_offset, &ci->root_size, &ci->root_checksum, + data_checksum, true, false)); /* * Checkpoints are potentially reading/writing/merging lots of blocks, @@ -824,7 +824,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->root_offset, (uintmax_t)(ci->root_offset + ci->root_size), - ci->root_size, ci->root_cksum)); + ci->root_size, ci->root_checksum)); if (ci->alloc.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", alloc=[Empty]")); else @@ -833,7 +833,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->alloc.offset, (uintmax_t)(ci->alloc.offset + ci->alloc.size), - ci->alloc.size, ci->alloc.cksum)); + ci->alloc.size, ci->alloc.checksum)); if (ci->avail.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", avail=[Empty]")); else @@ -842,7 +842,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->avail.offset, (uintmax_t)(ci->avail.offset + ci->avail.size), - ci->avail.size, ci->avail.cksum)); + ci->avail.size, ci->avail.checksum)); if (ci->discard.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", discard=[Empty]")); else @@ -851,7 +851,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->discard.offset, (uintmax_t)(ci->discard.offset + ci->discard.size), - ci->discard.size, ci->discard.cksum)); + ci->discard.size, ci->discard.checksum)); WT_RET(__wt_buf_catfmt(session, buf, ", file size=%" PRIuMAX, (uintmax_t)ci->file_size)); diff --git a/src/block/block_compact.c b/src/block/block_compact.c index 055cd3b6ceb..6d5d48bdb22 100644 --- a/src/block/block_compact.c +++ b/src/block/block_compact.c @@ -157,13 +157,14 @@ __wt_block_compact_page_skip(WT_SESSION_IMPL *session, WT_EXT *ext; WT_EXTLIST *el; wt_off_t limit, offset; - uint32_t size, cksum; + uint32_t size, checksum; WT_UNUSED(addr_size); *skipp = true; /* Return a default skip. */ /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* * If this block is in the chosen percentage of the file and there's a diff --git a/src/block/block_ext.c b/src/block/block_ext.c index d618bf70010..8a4d2b08bef 100644 --- a/src/block/block_ext.c +++ b/src/block/block_ext.c @@ -587,13 +587,14 @@ __wt_block_free(WT_SESSION_IMPL *session, { WT_DECL_RET; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); WT_STAT_FAST_DATA_INCR(session, block_free); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); __wt_verbose(session, WT_VERB_BLOCK, "free %" PRIdMAX "/%" PRIdMAX, (intmax_t)offset, (intmax_t)size); @@ -1174,7 +1175,7 @@ __wt_block_extlist_read(WT_SESSION_IMPL *session, WT_RET(__wt_scr_alloc(session, el->size, &tmp)); WT_ERR(__wt_block_read_off( - session, block, tmp, el->offset, el->size, el->cksum)); + session, block, tmp, el->offset, el->size, el->checksum)); #define WT_EXTLIST_READ(p, v) do { \ uint64_t _v; \ @@ -1257,7 +1258,7 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, entries = el->entries + (additional == NULL ? 0 : additional->entries); if (entries == 0) { el->offset = WT_BLOCK_INVALID_OFFSET; - el->cksum = el->size = 0; + el->checksum = el->size = 0; return (0); } @@ -1309,8 +1310,8 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, #endif /* Write the extent list to disk. */ - WT_ERR(__wt_block_write_off(session, - block, tmp, &el->offset, &el->size, &el->cksum, true, true, true)); + WT_ERR(__wt_block_write_off(session, block, + tmp, &el->offset, &el->size, &el->checksum, true, true, true)); /* * Remove the allocated blocks from the system's allocation list, extent diff --git a/src/block/block_mgr.c b/src/block/block_mgr.c index db52ad036e2..653ae3dbb6b 100644 --- a/src/block/block_mgr.c +++ b/src/block/block_mgr.c @@ -61,11 +61,11 @@ __bm_block_header(WT_BM *bm) * Write a buffer into a block, creating a checkpoint. */ static int -__bm_checkpoint(WT_BM *bm, - WT_SESSION_IMPL *session, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) +__bm_checkpoint(WT_BM *bm, WT_SESSION_IMPL *session, + WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { return (__wt_block_checkpoint( - session, bm->block, buf, ckptbase, data_cksum)); + session, bm->block, buf, ckptbase, data_checksum)); } /* @@ -73,12 +73,12 @@ __bm_checkpoint(WT_BM *bm, * Write a buffer into a block, creating a checkpoint; readonly version. */ static int -__bm_checkpoint_readonly(WT_BM *bm, - WT_SESSION_IMPL *session, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) +__bm_checkpoint_readonly(WT_BM *bm, WT_SESSION_IMPL *session, + WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { WT_UNUSED(buf); WT_UNUSED(ckptbase); - WT_UNUSED(data_cksum); + WT_UNUSED(data_checksum); return (__bm_readonly(bm, session)); } @@ -480,10 +480,10 @@ __bm_verify_start(WT_BM *bm, */ static int __bm_write(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, - uint8_t *addr, size_t *addr_sizep, bool data_cksum, bool checkpoint_io) + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { return (__wt_block_write(session, - bm->block, buf, addr, addr_sizep, data_cksum, checkpoint_io)); + bm->block, buf, addr, addr_sizep, data_checksum, checkpoint_io)); } /* @@ -493,12 +493,12 @@ __bm_write(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, */ static int __bm_write_readonly(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, - uint8_t *addr, size_t *addr_sizep, bool data_cksum, bool checkpoint_io) + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { WT_UNUSED(buf); WT_UNUSED(addr); WT_UNUSED(addr_sizep); - WT_UNUSED(data_cksum); + WT_UNUSED(data_checksum); WT_UNUSED(checkpoint_io); return (__bm_readonly(bm, session)); diff --git a/src/block/block_open.c b/src/block/block_open.c index b975f1612cc..e369d013437 100644 --- a/src/block/block_open.c +++ b/src/block/block_open.c @@ -290,11 +290,11 @@ __wt_desc_write(WT_SESSION_IMPL *session, WT_FH *fh, uint32_t allocsize) desc->magic = WT_BLOCK_MAGIC; desc->majorv = WT_BLOCK_MAJOR_VERSION; desc->minorv = WT_BLOCK_MINOR_VERSION; - desc->cksum = 0; + desc->checksum = 0; __wt_block_desc_byteswap(desc); - desc->cksum = __wt_cksum(desc, allocsize); + desc->checksum = __wt_checksum(desc, allocsize); #ifdef WORDS_BIGENDIAN - desc->cksum = __wt_bswap32(desc->cksum); + desc->checksum = __wt_bswap32(desc->checksum); #endif ret = __wt_write(session, fh, (wt_off_t)0, (size_t)allocsize, desc); @@ -312,7 +312,7 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_BLOCK_DESC *desc; WT_DECL_ITEM(buf); WT_DECL_RET; - uint32_t cksum_calculate, cksum_tmp; + uint32_t checksum_calculate, checksum_tmp; /* If in-memory, we don't read or write the descriptor structure. */ if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) @@ -333,10 +333,10 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) * a calculated checksum that should match the checksum in the header. */ desc = buf->mem; - cksum_tmp = desc->cksum; - desc->cksum = 0; - cksum_calculate = __wt_cksum(desc, block->allocsize); - desc->cksum = cksum_tmp; + checksum_tmp = desc->checksum; + desc->checksum = 0; + checksum_calculate = __wt_checksum(desc, block->allocsize); + desc->checksum = checksum_tmp; __wt_block_desc_byteswap(desc); /* @@ -348,7 +348,8 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) * may have entered the wrong file name, and is now frantically pounding * their interrupt key. */ - if (desc->magic != WT_BLOCK_MAGIC || desc->cksum != cksum_calculate) + if (desc->magic != WT_BLOCK_MAGIC || + desc->checksum != checksum_calculate) WT_ERR_MSG(session, WT_ERROR, "%s does not appear to be a WiredTiger file", block->name); @@ -368,7 +369,7 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) ", checksum %#" PRIx32, block->name, desc->magic, desc->majorv, desc->minorv, - desc->cksum); + desc->checksum); err: __wt_scr_free(session, &buf); return (ret); diff --git a/src/block/block_read.c b/src/block/block_read.c index 6706800409c..c6005b1f60a 100644 --- a/src/block/block_read.c +++ b/src/block/block_read.c @@ -21,7 +21,7 @@ __wt_bm_preload( WT_DECL_RET; WT_FILE_HANDLE *handle; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; bool mapped; WT_UNUSED(addr_size); @@ -31,7 +31,8 @@ __wt_bm_preload( WT_STAT_FAST_CONN_INCR(session, block_preload); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); handle = block->fh->handle; mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen; @@ -64,14 +65,15 @@ __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_DECL_RET; WT_FILE_HANDLE *handle; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; bool mapped; WT_UNUSED(addr_size); block = bm->block; /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* * Map the block if it's possible. @@ -98,7 +100,8 @@ __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, session, block, "read", offset, size, bm->is_live)); #endif /* Read the block. */ - WT_RET(__wt_block_read_off(session, block, buf, offset, size, cksum)); + WT_RET( + __wt_block_read_off(session, block, buf, offset, size, checksum)); /* Optionally discard blocks from the system's buffer cache. */ WT_RET(__wt_block_discard(session, block, (size_t)size)); @@ -117,7 +120,7 @@ __wt_block_read_off_blind( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset) { WT_BLOCK_HEADER *blk; - uint32_t cksum, size; + uint32_t checksum, size; /* * Make sure the buffer is large enough for the header and read the @@ -134,13 +137,14 @@ __wt_block_read_off_blind( * and if the size isn't insane, read the rest of the block. */ size = blk->disk_size; - cksum = blk->cksum; + checksum = blk->checksum; if (__wt_block_offset_invalid(block, offset, size)) WT_RET_MSG(session, EINVAL, "block at offset %" PRIuMAX " cannot be a valid block, no " "read attempted", (uintmax_t)offset); - return (__wt_block_read_off(session, block, buf, offset, size, cksum)); + return ( + __wt_block_read_off(session, block, buf, offset, size, checksum)); } #endif @@ -150,15 +154,15 @@ __wt_block_read_off_blind( */ int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t cksum) + WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t checksum) { WT_BLOCK_HEADER *blk, swap; size_t bufsize; - uint32_t page_cksum; + uint32_t page_checksum; __wt_verbose(session, WT_VERB_READ, - "off %" PRIuMAX ", size %" PRIu32 ", cksum %" PRIu32, - (uintmax_t)offset, size, cksum); + "off %" PRIuMAX ", size %" PRIu32 ", checksum %" PRIu32, + (uintmax_t)offset, size, checksum); WT_STAT_FAST_CONN_INCR(session, block_read); WT_STAT_FAST_CONN_INCRV(session, block_byte_read, size); @@ -189,12 +193,12 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, */ blk = WT_BLOCK_HEADER_REF(buf->mem); __wt_block_header_byteswap_copy(blk, &swap); - if (swap.cksum == cksum) { - blk->cksum = 0; - page_cksum = __wt_cksum(buf->mem, + if (swap.checksum == checksum) { + blk->checksum = 0; + page_checksum = __wt_checksum(buf->mem, F_ISSET(&swap, WT_BLOCK_DATA_CKSUM) ? size : WT_BLOCK_COMPRESS_SKIP); - if (page_cksum == cksum) { + if (page_checksum == checksum) { /* * Swap the page-header as needed; this doesn't belong * here, but it's the best place to catch all callers. @@ -209,7 +213,7 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, "offset %" PRIuMAX ": calculated block checksum " "of %" PRIu32 " doesn't match expected checksum " "of %" PRIu32, - size, (uintmax_t)offset, page_cksum, cksum); + size, (uintmax_t)offset, page_checksum, checksum); } else if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) __wt_errx(session, @@ -217,7 +221,7 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, "offset %" PRIuMAX ": block header checksum " "of %" PRIu32 " doesn't match expected checksum " "of %" PRIu32, - size, (uintmax_t)offset, swap.cksum, cksum); + size, (uintmax_t)offset, swap.checksum, checksum); /* Panic if a checksum fails during an ordinary read. */ return (block->verify || diff --git a/src/block/block_slvg.c b/src/block/block_slvg.c index 1bfc67f45e2..5ba95bb598e 100644 --- a/src/block/block_slvg.c +++ b/src/block/block_slvg.c @@ -98,7 +98,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, WT_DECL_RET; WT_FH *fh; wt_off_t max, offset; - uint32_t allocsize, cksum, size; + uint32_t allocsize, checksum, size; uint8_t *endp; *eofp = 0; @@ -125,7 +125,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, blk = WT_BLOCK_HEADER_REF(tmp->mem); __wt_block_header_byteswap(blk); size = blk->disk_size; - cksum = blk->cksum; + checksum = blk->checksum; /* * Check the block size: if it's not insane, read the block. @@ -135,7 +135,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, */ if (!__wt_block_offset_invalid(block, offset, size) && __wt_block_read_off( - session, block, tmp, offset, size, cksum) == 0) + session, block, tmp, offset, size, checksum) == 0) break; /* Free the allocation-size block. */ @@ -149,7 +149,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, /* Re-create the address cookie that should reference this block. */ endp = addr; - WT_ERR(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum)); + WT_ERR(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum)); *addr_sizep = WT_PTRDIFF(endp, addr); done: @@ -166,7 +166,7 @@ __wt_block_salvage_valid(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t addr_size, bool valid) { wt_off_t offset; - uint32_t size, cksum; + uint32_t size, checksum; WT_UNUSED(session); WT_UNUSED(addr_size); @@ -176,7 +176,8 @@ __wt_block_salvage_valid(WT_SESSION_IMPL *session, * If the upper layer took the block, move past it; if the upper layer * rejected the block, move past an allocation size chunk and free it. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); if (valid) block->slvg_off = offset + size; else { diff --git a/src/block/block_vrfy.c b/src/block/block_vrfy.c index 81b6059ab25..58b62247044 100644 --- a/src/block/block_vrfy.c +++ b/src/block/block_vrfy.c @@ -344,12 +344,13 @@ __wt_block_verify_addr(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* Add to the per-file list. */ WT_RET( diff --git a/src/block/block_write.c b/src/block/block_write.c index 36159314a4a..032f72d551b 100644 --- a/src/block/block_write.c +++ b/src/block/block_write.c @@ -202,17 +202,17 @@ __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep) */ int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, - uint8_t *addr, size_t *addr_sizep, bool data_cksum, bool checkpoint_io) + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { wt_off_t offset; - uint32_t size, cksum; + uint32_t checksum, size; uint8_t *endp; - WT_RET(__wt_block_write_off(session, block, - buf, &offset, &size, &cksum, data_cksum, checkpoint_io, false)); + WT_RET(__wt_block_write_off(session, block, buf, + &offset, &size, &checksum, data_checksum, checkpoint_io, false)); endp = addr; - WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum)); + WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum)); *addr_sizep = WT_PTRDIFF(endp, addr); return (0); @@ -225,15 +225,15 @@ __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, */ static int __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump, - bool data_cksum, bool checkpoint_io, bool caller_locked) + WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, + bool data_checksum, bool checkpoint_io, bool caller_locked) { WT_BLOCK_HEADER *blk; WT_DECL_RET; WT_FH *fh; size_t align_size; wt_off_t offset; - uint32_t cksum; + uint32_t checksum; bool local_locked; fh = block->fh; @@ -298,14 +298,14 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, * big-endian format, swap it into place in a separate step. */ blk->flags = 0; - if (data_cksum) + if (data_checksum) F_SET(blk, WT_BLOCK_DATA_CKSUM); - blk->cksum = 0; + blk->checksum = 0; __wt_block_header_byteswap(blk); - blk->cksum = cksum = __wt_cksum( - buf->mem, data_cksum ? align_size : WT_BLOCK_COMPRESS_SKIP); + blk->checksum = checksum = __wt_checksum( + buf->mem, data_checksum ? align_size : WT_BLOCK_COMPRESS_SKIP); #ifdef WORDS_BIGENDIAN - blk->cksum = __wt_bswap32(blk->cksum); + blk->checksum = __wt_bswap32(blk->checksum); #endif /* Pre-allocate some number of extension structures. */ @@ -370,12 +370,12 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, session, block_byte_write_checkpoint, align_size); __wt_verbose(session, WT_VERB_WRITE, - "off %" PRIuMAX ", size %" PRIuMAX ", cksum %" PRIu32, - (uintmax_t)offset, (uintmax_t)align_size, cksum); + "off %" PRIuMAX ", size %" PRIuMAX ", checksum %" PRIu32, + (uintmax_t)offset, (uintmax_t)align_size, checksum); *offsetp = offset; *sizep = WT_STORE_SIZE(align_size); - *cksump = cksum; + *checksump = checksum; return (0); } @@ -387,8 +387,8 @@ __block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, */ int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump, - bool data_cksum, bool checkpoint_io, bool caller_locked) + WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, + bool data_checksum, bool checkpoint_io, bool caller_locked) { WT_DECL_RET; @@ -399,8 +399,8 @@ __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, * than their original content. */ __wt_page_header_byteswap(buf->mem); - ret = __block_write_off(session, block, buf, - offsetp, sizep, cksump, data_cksum, checkpoint_io, caller_locked); + ret = __block_write_off(session, block, buf, offsetp, + sizep, checksump, data_checksum, checkpoint_io, caller_locked); __wt_page_header_byteswap(buf->mem); return (ret); } diff --git a/src/btree/bt_debug.c b/src/btree/bt_debug.c index 515d0cd6135..bcc7d27a569 100644 --- a/src/btree/bt_debug.c +++ b/src/btree/bt_debug.c @@ -291,7 +291,7 @@ err: __wt_scr_free(session, &buf); */ int __wt_debug_offset(WT_SESSION_IMPL *session, - wt_off_t offset, uint32_t size, uint32_t cksum, const char *ofile) + wt_off_t offset, uint32_t size, uint32_t checksum, const char *ofile) { WT_DECL_ITEM(buf); WT_DECL_RET; @@ -310,7 +310,7 @@ __wt_debug_offset(WT_SESSION_IMPL *session, */ endp = addr; WT_RET(__wt_block_addr_to_buffer( - S2BT(session)->bm->block, &endp, offset, size, cksum)); + S2BT(session)->bm->block, &endp, offset, size, checksum)); /* * Read the address through the btree I/O functions (so the block is diff --git a/src/btree/bt_io.c b/src/btree/bt_io.c index 6c2e2f1b3fb..8053417f838 100644 --- a/src/btree/bt_io.c +++ b/src/btree/bt_io.c @@ -182,7 +182,7 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t dst_len, len, result_len, size, src_len; int compression_failed; /* Extension API, so not a bool. */ uint8_t *dst, *src; - bool data_cksum, encrypted; + bool data_checksum, encrypted; btree = S2BT(session); bm = btree->bm; @@ -344,24 +344,24 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, * Checksum the data if the buffer isn't compressed or checksums are * configured. */ - data_cksum = true; /* -Werror=maybe-uninitialized */ + data_checksum = true; /* -Werror=maybe-uninitialized */ switch (btree->checksum) { case CKSUM_ON: - data_cksum = true; + data_checksum = true; break; case CKSUM_OFF: - data_cksum = false; + data_checksum = false; break; case CKSUM_UNCOMPRESSED: - data_cksum = !compressed; + data_checksum = !compressed; break; } /* Call the block manager to write the block. */ WT_ERR(checkpoint ? - bm->checkpoint(bm, session, ip, btree->ckpt, data_cksum) : + bm->checkpoint(bm, session, ip, btree->ckpt, data_checksum) : bm->write( - bm, session, ip, addr, addr_sizep, data_cksum, checkpoint_io)); + bm, session, ip, addr, addr_sizep, data_checksum, checkpoint_io)); WT_STAT_FAST_CONN_INCR(session, cache_write); WT_STAT_FAST_DATA_INCR(session, cache_write); diff --git a/src/checksum/arm64/crc32-arm64.c b/src/checksum/arm64/crc32-arm64.c new file mode 100644 index 00000000000..5d6c5f69c58 --- /dev/null +++ b/src/checksum/arm64/crc32-arm64.c @@ -0,0 +1,101 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "wt_internal.h" + +#if defined(HAVE_CRC32_HARDWARE) +#include <asm/hwcap.h> +#include <sys/auxv.h> + +#define CRC32CX(crc,value) \ + asm("crc32cx %w[c], %w[c], %x[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CW(crc,value) \ + asm("crc32cw %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CH(crc,value) \ + asm("crc32ch %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CB(crc,value) \ + asm("crc32cb %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) + +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_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) { + CRC32CB(crc, *p); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + CRC32CX(crc, *p64); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + CRC32CB(crc, *p); + } + + return (~crc); +} +#endif /* HAVE_CRC32_HARDWARE */ + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) + unsigned long caps = getauxval(AT_HWCAP); + + if (caps & HWCAP_CRC32) + __wt_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; + +#else /* !HAVE_CRC32_HARDWARE */ + __wt_process.checksum = __wt_checksum_sw; +#endif /* HAVE_CRC32_HARDWARE */ +} diff --git a/src/checksum/power8/crc32_wrapper.c b/src/checksum/power8/crc32_wrapper.c index cbfe1ab90f5..ddfa2bdaeb8 100644 --- a/src/checksum/power8/crc32_wrapper.c +++ b/src/checksum/power8/crc32_wrapper.c @@ -71,21 +71,25 @@ out: #include "wt_internal.h" /* - * __wt_cksum -- + * __wt_checksum_hw -- * WiredTiger: return a checksum for a chunk of memory. */ -uint32_t -__wt_cksum(const void *chunk, size_t len) +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) { - return crc32_vpmsum(0, chunk, len); + return (crc32_vpmsum(0, chunk, len)); } /* - * __wt_cksum_init -- + * __wt_checksum_init -- * WiredTiger: detect CRC hardware and set the checksum function. */ void -__wt_cksum_init(void) +__wt_checksum_init(void) { - /* None needed. */ +#if defined(HAVE_CRC32_HARDWARE) + __wt_process.checksum = __wt_checksum_hw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif } diff --git a/src/checksum/x86/checksum.c b/src/checksum/software/checksum.c index 8a8c735cfc8..30362584a3e 100644 --- a/src/checksum/x86/checksum.c +++ b/src/checksum/software/checksum.c @@ -41,15 +41,7 @@ #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_func)(const void *chunk, size_t len); - -/* - * The CRC slicing tables are used by __wt_cksum_sw. + * The CRC slicing tables. */ static const uint32_t g_crc_slicing[8][256] = { #ifdef WORDS_BIGENDIAN @@ -1104,11 +1096,11 @@ static const uint32_t g_crc_slicing[8][256] = { }; /* - * __wt_cksum_sw -- + * __wt_checksum_sw -- * Return a checksum for a chunk of memory, computed in software. */ -static uint32_t -__wt_cksum_sw(const void *chunk, size_t len) +uint32_t +__wt_checksum_sw(const void *chunk, size_t len) { uint32_t crc, next; size_t nqwords; @@ -1171,137 +1163,3 @@ __wt_cksum_sw(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 - -#if defined(_M_AMD64) -/* - * __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) { - crc = _mm_crc32_u8(crc, *p); - } - - p64 = (const uint64_t *)p; - /* Checksum in 8B chunks. */ - for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { - crc = (uint32_t)_mm_crc32_u64(crc, *p64); - p64++; - } - - /* Checksum trailing bytes one byte at a time. */ - p = (const uint8_t *)p64; - for (len &= 0x7; len > 0; ++p, len--) { - crc = _mm_crc32_u8(crc, *p); - } - - return (~crc); -} -#endif - -/* - * __wt_cksum -- - * WiredTiger: return a checksum for a chunk of memory. - */ -uint32_t -__wt_cksum(const void *chunk, size_t len) -{ - return (*__wt_cksum_func)(chunk, len); -} - -/* - * __wt_cksum_init -- - * WiredTiger: detect CRC hardware and set the checksum function. - */ -void -__wt_cksum_init(void) -{ -#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; - -#elif defined(_M_AMD64) - int cpuInfo[4]; - - __cpuid(cpuInfo, 1); - -#define CPUID_ECX_HAS_SSE42 (1 << 20) - if (cpuInfo[2] & 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/checksum/x86/crc32-x86.c b/src/checksum/x86/crc32-x86.c new file mode 100644 index 00000000000..82814ecc34d --- /dev/null +++ b/src/checksum/x86/crc32-x86.c @@ -0,0 +1,160 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "wt_internal.h" + +#if defined(HAVE_CRC32_HARDWARE) +#if (defined(__amd64) || defined(__x86_64)) +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_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 + +#if defined(_M_AMD64) +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_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) { + crc = _mm_crc32_u8(crc, *p); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + crc = (uint32_t)_mm_crc32_u64(crc, *p64); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + crc = _mm_crc32_u8(crc, *p); + } + + return (~crc); +} +#endif +#endif /* HAVE_CRC32_HARDWARE */ + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) +#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_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; + +#elif defined(_M_AMD64) + int cpuInfo[4]; + + __cpuid(cpuInfo, 1); + +#define CPUID_ECX_HAS_SSE42 (1 << 20) + if (cpuInfo[2] & CPUID_ECX_HAS_SSE42) + __wt_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif + +#else /* !HAVE_CRC32_HARDWARE */ + __wt_process.checksum = __wt_checksum_sw; +#endif /* HAVE_CRC32_HARDWARE */ +} diff --git a/src/checksum/zseries/crc32-s390x.c b/src/checksum/zseries/crc32-s390x.c index daf7ce06c53..f77d6768d42 100644 --- a/src/checksum/zseries/crc32-s390x.c +++ b/src/checksum/zseries/crc32-s390x.c @@ -72,21 +72,25 @@ DEFINE_CRC32_VX(__wt_crc32c_le_vx, __wt_crc32c_le_vgfm_16, __wt_crc32c_le) #include "wt_internal.h" /* - * __wt_cksum -- + * __wt_checksum_hw -- * WiredTiger: return a checksum for a chunk of memory. */ -unsigned int -__wt_cksum(const void *chunk, size_t len) +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) { return (~__wt_crc32c_le_vx(0xffffffff, chunk, len)); } /* - * __wt_cksum_init -- + * __wt_checksum_init -- * WiredTiger: detect CRC hardware and set the checksum function. */ void -__wt_cksum_init(void) +__wt_checksum_init(void) { - /* None needed. */ +#if defined(HAVE_CRC32_HARDWARE) + __wt_process.checksum = __wt_checksum_hw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif } diff --git a/src/include/block.h b/src/include/block.h index 3342f9b1e5e..0cf76e34367 100644 --- a/src/include/block.h +++ b/src/include/block.h @@ -52,7 +52,8 @@ struct __wt_extlist { uint32_t entries; /* Entry count */ wt_off_t offset; /* Written extent offset */ - uint32_t cksum, size; /* Written extent cksum, size */ + uint32_t checksum; /* Written extent checksum */ + uint32_t size; /* Written extent size */ bool track_size; /* Maintain per-size skiplist */ @@ -128,7 +129,7 @@ struct __wt_block_ckpt { uint8_t version; /* Version */ wt_off_t root_offset; /* The root */ - uint32_t root_cksum, root_size; + uint32_t root_checksum, root_size; WT_EXTLIST alloc; /* Extents allocated */ WT_EXTLIST avail; /* Extents available */ @@ -282,7 +283,7 @@ struct __wt_block_desc { #define WT_BLOCK_MINOR_VERSION 0 uint16_t minorv; /* 06-07: Minor version */ - uint32_t cksum; /* 08-11: Description block checksum */ + uint32_t checksum; /* 08-11: Description block checksum */ uint32_t unused; /* 12-15: Padding */ }; @@ -305,7 +306,7 @@ __wt_block_desc_byteswap(WT_BLOCK_DESC *desc) desc->magic = __wt_bswap32(desc->magic); desc->majorv = __wt_bswap16(desc->majorv); desc->minorv = __wt_bswap16(desc->minorv); - desc->cksum = __wt_bswap32(desc->cksum); + desc->checksum = __wt_bswap32(desc->checksum); #else WT_UNUSED(desc); #endif @@ -335,7 +336,7 @@ struct __wt_block_header { * stored in the disk header. This is for salvage, so salvage knows it * has found a page that may be useful. */ - uint32_t cksum; /* 04-07: checksum */ + uint32_t checksum; /* 04-07: checksum */ #define WT_BLOCK_DATA_CKSUM 0x01 /* Block data is part of the checksum */ uint8_t flags; /* 08: flags */ @@ -364,7 +365,7 @@ __wt_block_header_byteswap_copy(WT_BLOCK_HEADER *from, WT_BLOCK_HEADER *to) *to = *from; #ifdef WORDS_BIGENDIAN to->disk_size = __wt_bswap32(from->disk_size); - to->cksum = __wt_bswap32(from->cksum); + to->checksum = __wt_bswap32(from->checksum); #endif } diff --git a/src/include/btmem.h b/src/include/btmem.h index 9765f8ea03f..b4ca937e7ed 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -311,7 +311,7 @@ struct __wt_page_modify { */ WT_ADDR addr; uint32_t size; - uint32_t cksum; + uint32_t checksum; } *multi; uint32_t multi_entries; /* Multiple blocks element count */ } m; diff --git a/src/include/connection.h b/src/include/connection.h index e4ba6ffc046..77dbc87b114 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -25,6 +25,10 @@ struct __wt_process { /* Locked: connection queue */ TAILQ_HEAD(__wt_connection_impl_qh, __wt_connection_impl) connqh; WT_CACHE_POOL *cache_pool; + + /* Checksum function */ +#define __wt_checksum(chunk, len) __wt_process.checksum(chunk, len) + uint32_t (*checksum)(const void *, size_t); }; extern WT_PROCESS __wt_process; diff --git a/src/include/extern.h b/src/include/extern.h index 90c7d884f3c..5444b2e9f14 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -9,8 +9,8 @@ extern int __wt_async_new_op(WT_SESSION_IMPL *session, const char *uri, const ch extern int __wt_async_op_enqueue(WT_SESSION_IMPL *session, WT_ASYNC_OP_IMPL *op) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_async_op_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern WT_THREAD_RET __wt_async_worker(void *arg); -extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t cksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_buffer_to_ckpt(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); @@ -20,7 +20,7 @@ extern int __wt_block_ckpt_init( WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, co extern int __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, uint8_t *root_addr, size_t *root_addr_sizep, bool checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_checkpoint_unload( WT_SESSION_IMPL *session, WT_BLOCK *block, bool checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_ckpt_destroy(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci); -extern int __wt_block_checkpoint(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_checkpoint(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_checkpoint_resolve(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_compact_start(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_compact_end(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); @@ -57,7 +57,7 @@ extern int __wt_block_manager_named_size( WT_SESSION_IMPL *session, const char * extern int __wt_bm_preload( WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_read_off_blind( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t cksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_ext_alloc(WT_SESSION_IMPL *session, WT_EXT **extp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_ext_free(WT_SESSION_IMPL *session, WT_EXT *ext); extern int __wt_block_size_alloc(WT_SESSION_IMPL *session, WT_SIZE **szp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); @@ -77,8 +77,8 @@ extern int __wt_block_verify_addr(WT_SESSION_IMPL *session, WT_BLOCK *block, con extern int __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_discard(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t added_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum, bool checkpoint_io) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump, bool data_cksum, bool checkpoint_io, bool caller_locked) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io, bool caller_locked) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_bloom_create( WT_SESSION_IMPL *session, const char *uri, const char *config, uint64_t count, uint32_t factor, uint32_t k, WT_BLOOM **bloomp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_bloom_open(WT_SESSION_IMPL *session, const char *uri, uint32_t factor, uint32_t k, WT_CURSOR *owner, WT_BLOOM **bloomp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key); @@ -116,7 +116,7 @@ extern int __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v) WT_GC extern int __wt_debug_addr_print( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_debug_addr(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_debug_offset_blind( WT_SESSION_IMPL *session, wt_off_t offset, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_debug_offset(WT_SESSION_IMPL *session, wt_off_t offset, uint32_t size, uint32_t cksum, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_offset(WT_SESSION_IMPL *session, wt_off_t offset, uint32_t size, uint32_t checksum, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_debug_disk( WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_debug_tree_shape( WT_SESSION_IMPL *session, WT_PAGE *page, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_debug_tree_all( WT_SESSION_IMPL *session, WT_BTREE *btree, WT_REF *ref, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); @@ -203,8 +203,8 @@ extern int __wt_las_cursor_open(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) W extern void __wt_las_cursor( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t *session_flags); extern int __wt_las_cursor_close( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t session_flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_las_sweep(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern uint32_t __wt_cksum(const void *chunk, size_t len); -extern void __wt_cksum_init(void); +extern uint32_t __wt_checksum_sw(const void *chunk, size_t len); +extern void __wt_checksum_init(void); extern void __wt_config_initn( WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str, size_t len); extern void __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str); extern void __wt_config_subinit( WT_SESSION_IMPL *session, WT_CONFIG *conf, WT_CONFIG_ITEM *item); diff --git a/src/log/log.c b/src/log/log.c index ec1bd10d0bc..b17f31d5d16 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -640,7 +640,7 @@ __log_file_header( logrec->len = log->allocsize; logrec->checksum = 0; __wt_log_record_byteswap(logrec); - logrec->checksum = __wt_cksum(logrec, log->allocsize); + logrec->checksum = __wt_checksum(logrec, log->allocsize); #ifdef WORDS_BIGENDIAN logrec->checksum = __wt_bswap32(logrec->checksum); #endif @@ -1547,7 +1547,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, WT_LSN end_lsn, next_lsn, rd_lsn, start_lsn; wt_off_t log_size; uint32_t allocsize, firstlog, lastlog, lognum, rdup_len, reclen; - uint32_t cksum_calculate, cksum_tmp; + uint32_t checksum_calculate, checksum_tmp; u_int i, logcount; int firstrecord; bool eol, partial_record; @@ -1759,12 +1759,12 @@ advance: */ buf->size = reclen; logrec = (WT_LOG_RECORD *)buf->mem; - cksum_tmp = logrec->checksum; + checksum_tmp = logrec->checksum; logrec->checksum = 0; - cksum_calculate = __wt_cksum(logrec, reclen); - logrec->checksum = cksum_tmp; + checksum_calculate = __wt_checksum(logrec, reclen); + logrec->checksum = checksum_tmp; __wt_log_record_byteswap(logrec); - if (logrec->checksum != cksum_calculate) { + if (logrec->checksum != checksum_calculate) { /* * A checksum mismatch means we have reached the end of * the useful part of the log. This should be found on @@ -2078,7 +2078,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, logrec->len = (uint32_t)record->size; logrec->checksum = 0; __wt_log_record_byteswap(logrec); - logrec->checksum = __wt_cksum(logrec, record->size); + logrec->checksum = __wt_checksum(logrec, record->size); #ifdef WORDS_BIGENDIAN logrec->checksum = __wt_bswap32(logrec->checksum); #endif diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index 31a69c2604f..a9912628942 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -159,7 +159,7 @@ typedef struct { WT_ADDR addr; /* Split's written location */ uint32_t size; /* Split's size */ - uint32_t cksum; /* Split's checksum */ + uint32_t checksum; /* Split's checksum */ void *disk_image; /* Split's disk image */ @@ -1877,7 +1877,7 @@ __rec_split_bnd_init(WT_SESSION_IMPL *session, WT_BOUNDARY *bnd) __wt_free(session, bnd->addr.addr); WT_CLEAR(bnd->addr); bnd->size = 0; - bnd->cksum = 0; + bnd->checksum = 0; __wt_free(session, bnd->disk_image); @@ -3200,7 +3200,7 @@ __rec_split_write(WT_SESSION_IMPL *session, WT_ILLEGAL_VALUE(session); } bnd->size = (uint32_t)buf->size; - bnd->cksum = 0; + bnd->checksum = 0; /* * Check if we've saved updates that belong to this block, and move @@ -3306,7 +3306,7 @@ supd_check_complete: */ dsk->write_gen = 0; memset(WT_BLOCK_HEADER_REF(dsk), 0, btree->block_header); - bnd->cksum = __wt_cksum(buf->data, buf->size); + bnd->checksum = __wt_checksum(buf->data, buf->size); /* * One last check: don't reuse blocks if compacting, the reason @@ -3319,7 +3319,7 @@ supd_check_complete: mod->mod_multi_entries > bnd_slot) { multi = &mod->mod_multi[bnd_slot]; if (multi->size == bnd->size && - multi->cksum == bnd->cksum) { + multi->checksum == bnd->checksum) { multi->addr.reuse = 1; bnd->addr = multi->addr; @@ -5850,7 +5850,7 @@ __rec_split_row(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) multi->addr = bnd->addr; multi->addr.reuse = 0; multi->size = bnd->size; - multi->cksum = bnd->cksum; + multi->checksum = bnd->checksum; bnd->addr.addr = NULL; } mod->mod_multi_entries = r->bnd_next; @@ -5897,7 +5897,7 @@ __rec_split_col(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) multi->addr = bnd->addr; multi->addr.reuse = 0; multi->size = bnd->size; - multi->cksum = bnd->cksum; + multi->checksum = bnd->checksum; bnd->addr.addr = NULL; } mod->mod_multi_entries = r->bnd_next; diff --git a/src/support/global.c b/src/support/global.c index 325666b1471..aa69e0db9d6 100644 --- a/src/support/global.c +++ b/src/support/global.c @@ -55,7 +55,7 @@ __wt_global_once(void) return; } - __wt_cksum_init(); + __wt_checksum_init(); TAILQ_INIT(&__wt_process.connqh); diff --git a/src/utilities/util_list.c b/src/utilities/util_list.c index 57062b9e9b5..e91dbfce05b 100644 --- a/src/utilities/util_list.c +++ b/src/utilities/util_list.c @@ -238,7 +238,7 @@ list_print_checkpoint(WT_SESSION *session, const char *key) ci.root_size, ci.root_size); printf("\t\t" "root checksum: %" PRIu32 " (0x%" PRIx32 ")\n", - ci.root_cksum, ci.root_cksum); + ci.root_checksum, ci.root_checksum); } } diff --git a/test/csuite/Makefile.am b/test/csuite/Makefile.am index b8a62b69612..15db2fbcf46 100644 --- a/test/csuite/Makefile.am +++ b/test/csuite/Makefile.am @@ -1,6 +1,5 @@ AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include \ - -I$(top_srcdir)/test/utility \ - -DCRC_PATH="\"$(top_srcdir)/src/checksum/x86/checksum.c\"" + -I$(top_srcdir)/test/utility LDADD = $(top_builddir)/test/utility/libtest_util.la \ $(top_builddir)/libwiredtiger.la AM_LDFLAGS = -static @@ -20,7 +19,7 @@ noinst_PROGRAMS += test_wt2535_insert_race test_wt2447_join_main_table_SOURCES = wt2447_join_main_table/main.c noinst_PROGRAMS += test_wt2447_join_main_table -test_wt2695_checksum_SOURCES = wt2695_checksum/main.c wt2695_checksum/sw.c +test_wt2695_checksum_SOURCES = wt2695_checksum/main.c noinst_PROGRAMS += test_wt2695_checksum test_wt2592_join_schema_SOURCES = wt2592_join_schema/main.c diff --git a/test/csuite/wt2695_checksum/main.c b/test/csuite/wt2695_checksum/main.c index dc6f5b5cd87..df6f562f719 100644 --- a/test/csuite/wt2695_checksum/main.c +++ b/test/csuite/wt2695_checksum/main.c @@ -34,8 +34,6 @@ void (*custom_die)(void) = NULL; -uint32_t cksum_sw(const void *, size_t); - static inline void check(uint32_t hw, uint32_t sw, size_t len, const char *msg) { @@ -61,57 +59,66 @@ main(void) testutil_check(__wt_random_init_seed(NULL, &rnd)); /* Initialize the WiredTiger library checksum functions. */ - __wt_cksum_init(); + __wt_checksum_init(); /* * Some simple known checksums. */ len = 1; - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0x527d5351, len, "nul x1: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0x527d5351, len, "nul x1: software"); len = 2; - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0xf16177d2, len, "nul x2: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0xf16177d2, len, "nul x2: software"); len = 3; - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0x6064a37a, len, "nul x3: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0x6064a37a, len, "nul x3: software"); len = 4; - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0x48674bc7, len, "nul x4: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0x48674bc7, len, "nul x4: software"); len = strlen("123456789"); memcpy(data, "123456789", len); - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0xe3069283, len, "known string #1: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0xe3069283, len, "known string #1: software"); len = strlen("The quick brown fox jumps over the lazy dog"); memcpy(data, "The quick brown fox jumps over the lazy dog", len); - hw = __wt_cksum(data, len); + hw = __wt_checksum(data, len); check(hw, (uint32_t)0x22620404, len, "known string #2: hardware"); - sw = cksum_sw(data, len); + sw = __wt_checksum_sw(data, len); check(sw, (uint32_t)0x22620404, len, "known string #2: software"); /* + * Offset the string by 1 to ensure the hardware code handles unaligned + * reads. + */ + hw = __wt_checksum(data + 1, len - 1); + check(hw, (uint32_t)0xae11f7f5, len, "known string #2: hardware"); + sw = __wt_checksum_sw(data + 1, len - 1); + check(sw, (uint32_t)0xae11f7f5, len, "known string #2: software"); + + /* * Checksums of power-of-two data chunks. */ for (i = 0, len = 512; i < 1000; ++i) { for (j = 0; j < len; ++j) data[j] = __wt_random(&rnd) & 0xff; - hw = __wt_cksum(data, len); - sw = cksum_sw(data, len); + hw = __wt_checksum(data, len); + sw = __wt_checksum_sw(data, len); check(hw, sw, len, "random power-of-two"); len *= 2; @@ -126,8 +133,8 @@ main(void) len = __wt_random(&rnd) % DATASIZE; for (j = 0; j < len; ++j) data[j] = __wt_random(&rnd) & 0xff; - hw = __wt_cksum(data, len); - sw = cksum_sw(data, len); + hw = __wt_checksum(data, len); + sw = __wt_checksum_sw(data, len); check(hw, sw, len, "random"); } diff --git a/test/csuite/wt2695_checksum/sw.c b/test/csuite/wt2695_checksum/sw.c deleted file mode 100644 index 892d9480bf3..00000000000 --- a/test/csuite/wt2695_checksum/sw.c +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Public Domain 2014-2016 MongoDB, Inc. - * Public Domain 2008-2014 WiredTiger, Inc. - * - * This is free and unencumbered software released into the public domain. - * - * Anyone is free to copy, modify, publish, use, compile, sell, or - * distribute this software, either in source code form or as a compiled - * binary, for any purpose, commercial or non-commercial, and by any - * means. - * - * In jurisdictions that recognize copyright laws, the author or authors - * of this software dedicate any and all copyright interest in the - * software to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and - * successors. We intend this dedication to be an overt act of - * relinquishment in perpetuity of all present and future rights to this - * software under copyright law. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "test_util.h" - -/* - * Build the software version of the CRC code. - */ -#define __wt_cksum __wt_cksum_notused -uint32_t __wt_cksum_notused(const void *, size_t); -#define __wt_cksum_init __wt_cksum_init_notused -void __wt_cksum_init_notused(void); - -#include CRC_PATH - -/* - * cksum_sw -- - * Checksum in software. - */ -uint32_t cksum_sw(const void *, size_t); -uint32_t -cksum_sw(const void *chunk, size_t len) -{ - return (__wt_cksum_sw(chunk, len)); -} diff --git a/test/salvage/salvage.c b/test/salvage/salvage.c index c3349188623..bad0167ca8e 100644 --- a/test/salvage/salvage.c +++ b/test/salvage/salvage.c @@ -602,8 +602,8 @@ copy(u_int gen, u_int recno) dsk->recno = recno; dsk->write_gen = gen; blk = WT_BLOCK_HEADER_REF(buf); - blk->cksum = 0; - blk->cksum = __wt_cksum(dsk, PSIZE); + blk->checksum = 0; + blk->checksum = __wt_checksum(dsk, PSIZE); CHECK(fwrite(buf, 1, PSIZE, ofp) == PSIZE); } |