From: Sage Weil Date: Tue, 20 Aug 2013 18:55:10 +0000 (-0700) Subject: common/crc32c: refactor a bit X-Git-Tag: v0.69~78^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a286090602c4776adf53e17b98e8c7edd5bc3163;p=ceph.git common/crc32c: refactor a bit - the generic function without the _le suffix (useless) - use a static global so that detection only happens once - make the structure a bit cleaner to plug in new implementations Signed-off-by: Sage Weil --- diff --git a/src/Makefile.am b/src/Makefile.am index 5a0f3472080a..9a5f2a8ae0f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1534,6 +1534,7 @@ libcommon_files = \ common/Finisher.cc \ common/environment.cc\ common/sctp_crc32.c\ + common/crc32c.cc\ common/crc32c-intel.c\ common/assert.cc \ common/run_cmd.cc \ @@ -1885,6 +1886,7 @@ noinst_HEADERS = \ common/utf8.h\ common/mime.h\ common/pick_address.h\ + common/sctp_crc32.h\ common/secret.h\ common/strtol.h\ common/static_assert.h\ diff --git a/src/common/crc32c.cc b/src/common/crc32c.cc new file mode 100644 index 000000000000..84a5ef4f3e2b --- /dev/null +++ b/src/common/crc32c.cc @@ -0,0 +1,24 @@ +#include "include/crc32c.h" + +#include "common/sctp_crc32.h" + +/* + * choose best implementation based on the CPU architecture. + */ +ceph_crc32c_func_t ceph_choose_crc32(void) +{ + /* default */ + return ceph_crc32c_sctp; +} + +/* + * static global + * + * This is a bit of a no-no for shared libraries, but we don't care. + * It is effectively constant for the executing process as the value + * depends on the CPU architecture. + * + * We initialize it during program init using the magic of C++. + */ +ceph_crc32c_func_t ceph_crc32c_func = ceph_choose_crc32(); + diff --git a/src/common/sctp_crc32.c b/src/common/sctp_crc32.c index b11bb48dd87f..7e2678a2b7ce 100644 --- a/src/common/sctp_crc32.c +++ b/src/common/sctp_crc32.c @@ -728,7 +728,7 @@ sctp_csum_finalize(uint32_t crc32c) } #endif -uint32_t ceph_crc32c_le_generic(uint32_t crc, unsigned char const *data, unsigned length) +uint32_t ceph_crc32c_sctp(uint32_t crc, unsigned char const *data, unsigned length) { return update_crc32(crc, data, length); } diff --git a/src/common/sctp_crc32.h b/src/common/sctp_crc32.h new file mode 100644 index 000000000000..92d20bcb7cc5 --- /dev/null +++ b/src/common/sctp_crc32.h @@ -0,0 +1,14 @@ +#ifndef CEPH_COMMON_SCTP_CRC32_H +#define CEPH_COMMON_SCTP_CRC32_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t ceph_crc32c_sctp(uint32_t crc, unsigned char const *data, unsigned length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/buffer.h b/src/include/buffer.h index 8c4dfb56e174..8e637d658c51 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -425,7 +425,7 @@ public: it != _buffers.end(); ++it) if (it->length()) - crc = ceph_crc32c_le(crc, (unsigned char*)it->c_str(), it->length()); + crc = ceph_crc32c(crc, (unsigned char*)it->c_str(), it->length()); return crc; } diff --git a/src/include/crc32c.h b/src/include/crc32c.h index 3fd209efb02b..d5f7388be565 100644 --- a/src/include/crc32c.h +++ b/src/include/crc32c.h @@ -1,25 +1,25 @@ #ifndef CEPH_CRC32C_H #define CEPH_CRC32C_H -#ifdef __cplusplus -extern "C" { -#endif - +#include "include/inttypes.h" #include -extern int ceph_have_crc32c_intel(void); -extern uint32_t ceph_crc32c_le_generic(uint32_t crc, unsigned char const *data, unsigned length); -extern uint32_t ceph_crc32c_le_intel(uint32_t crc, unsigned char const *data, unsigned length); +typedef uint32_t (*ceph_crc32c_func_t)(uint32_t crc, unsigned char const *data, unsigned length); -static inline uint32_t ceph_crc32c_le(uint32_t crc, unsigned char const *data, unsigned length) { - if (ceph_have_crc32c_intel()) //__builtin_cpu_supports("sse4.2")) - return ceph_crc32c_le_intel(crc, data, length); - else - return ceph_crc32c_le_generic(crc, data, length); -} +/* + * this is a static global with the chosen crc32c implementation for + * the given architecture. + */ +extern ceph_crc32c_func_t ceph_crc32c_func; -#ifdef __cplusplus +extern ceph_crc32c_func_t ceph_choose_crc32(void); + +/* + * common entry point; use this! + */ +static inline uint32_t ceph_crc32c(uint32_t crc, unsigned char const *data, unsigned length) +{ + return ceph_crc32c_func(crc, data, length); } -#endif #endif diff --git a/src/msg/Message.h b/src/msg/Message.h index 3ed8ee667d24..f345e7adaabe 100644 --- a/src/msg/Message.h +++ b/src/msg/Message.h @@ -449,8 +449,8 @@ public: const utime_t& get_recv_complete_stamp() const { return recv_complete_stamp; } void calc_header_crc() { - header.crc = ceph_crc32c_le(0, (unsigned char*)&header, - sizeof(header) - sizeof(header.crc)); + header.crc = ceph_crc32c(0, (unsigned char*)&header, + sizeof(header) - sizeof(header.crc)); } void calc_front_crc() { footer.front_crc = payload.crc32c(0); diff --git a/src/msg/Pipe.cc b/src/msg/Pipe.cc index 6f271c812f38..50656fee53b9 100644 --- a/src/msg/Pipe.cc +++ b/src/msg/Pipe.cc @@ -1684,7 +1684,7 @@ int Pipe::read_message(Message **pm) if (connection_state->has_feature(CEPH_FEATURE_NOSRCADDR)) { if (tcp_read((char*)&header, sizeof(header)) < 0) return -1; - header_crc = ceph_crc32c_le(0, (unsigned char *)&header, sizeof(header) - sizeof(header.crc)); + header_crc = ceph_crc32c(0, (unsigned char *)&header, sizeof(header) - sizeof(header.crc)); } else { ceph_msg_header_old oldheader; if (tcp_read((char*)&oldheader, sizeof(oldheader)) < 0) @@ -1694,7 +1694,7 @@ int Pipe::read_message(Message **pm) header.src = oldheader.src.name; header.reserved = oldheader.reserved; header.crc = oldheader.crc; - header_crc = ceph_crc32c_le(0, (unsigned char *)&oldheader, sizeof(oldheader) - sizeof(oldheader.crc)); + header_crc = ceph_crc32c(0, (unsigned char *)&oldheader, sizeof(oldheader) - sizeof(oldheader.crc)); } ldout(msgr->cct,20) << "reader got envelope type=" << header.type @@ -2028,8 +2028,8 @@ int Pipe::write_message(ceph_msg_header& header, ceph_msg_footer& footer, buffer oldheader.src.addr = connection_state->get_peer_addr(); oldheader.orig_src = oldheader.src; oldheader.reserved = header.reserved; - oldheader.crc = ceph_crc32c_le(0, (unsigned char*)&oldheader, - sizeof(oldheader) - sizeof(oldheader.crc)); + oldheader.crc = ceph_crc32c(0, (unsigned char*)&oldheader, + sizeof(oldheader) - sizeof(oldheader.crc)); msgvec[msg.msg_iovlen].iov_base = (char*)&oldheader; msgvec[msg.msg_iovlen].iov_len = sizeof(oldheader); msglen += sizeof(oldheader);