1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
14 #ifndef CEPH_INLINE_MEMORY_H
15 #define CEPH_INLINE_MEMORY_H
19 // optimize for the common case, which is very small copies
20 static inline void *maybe_inline_memcpy(void *dest, const void *src, size_t l,
22 __attribute__((always_inline));
24 void *maybe_inline_memcpy(void *dest, const void *src, size_t l,
28 return memcpy(dest, src, l);
32 return __builtin_memcpy(dest, src, 8);
34 return __builtin_memcpy(dest, src, 4);
36 return __builtin_memcpy(dest, src, 3);
38 return __builtin_memcpy(dest, src, 2);
40 return __builtin_memcpy(dest, src, 1);
43 while (l >= sizeof(uint64_t)) {
44 __builtin_memcpy((char*)dest + cursor, (char*)src + cursor,
46 cursor += sizeof(uint64_t);
47 l -= sizeof(uint64_t);
49 while (l >= sizeof(uint32_t)) {
50 __builtin_memcpy((char*)dest + cursor, (char*)src + cursor,
52 cursor += sizeof(uint32_t);
53 l -= sizeof(uint32_t);
56 *((char*)dest + cursor) = *((char*)src + cursor);
66 #define maybe_inline_memcpy(d, s, l, x) memcpy(d, s, l)
71 #if defined(__GNUC__) && defined(__x86_64__)
73 typedef unsigned uint128_t __attribute__ ((mode (TI)));
75 static inline bool mem_is_zero(const char *data, size_t len)
76 __attribute__((always_inline));
78 bool mem_is_zero(const char *data, size_t len)
80 // we do have XMM registers in x86-64, so if we need to check at least
81 // 16 bytes, make use of them
82 if (len / sizeof(uint128_t) > 0) {
83 // align data pointer to 16 bytes, otherwise it'll segfault due to bug
84 // in (at least some) GCC versions (using MOVAPS instead of MOVUPS).
85 // check up to 15 first bytes while at it.
86 while (((unsigned long long)data) & 15) {
87 if (*(uint8_t*)data != 0) {
90 data += sizeof(uint8_t);
94 const char* data_start = data;
95 const char* max128 = data + (len / sizeof(uint128_t))*sizeof(uint128_t);
97 while (data < max128) {
98 if (*(uint128_t*)data != 0) {
101 data += sizeof(uint128_t);
103 len -= (data - data_start);
106 const char* max = data + len;
107 const char* max32 = data + (len / sizeof(uint32_t))*sizeof(uint32_t);
108 while (data < max32) {
109 if (*(uint32_t*)data != 0) {
112 data += sizeof(uint32_t);
115 if (*(uint8_t*)data != 0) {
118 data += sizeof(uint8_t);
123 #else // gcc and x86_64
125 static inline bool mem_is_zero(const char *data, size_t len) {
126 const char *end = data + len;
127 const char* end64 = data + (len / sizeof(uint64_t))*sizeof(uint64_t);
129 while (data < end64) {
130 if (*(uint64_t*)data != 0) {
133 data += sizeof(uint64_t);