]>
git.proxmox.com Git - ceph.git/blob - ceph/src/include/inline_memory.h
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);