]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/core/unaligned.hh
import quincy beta 17.1.0
[ceph.git] / ceph / src / seastar / include / seastar / core / unaligned.hh
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2015 Cloudius Systems, Ltd.
20 */
21
22 #pragma once
23
24 // The following unaligned_cast<T*>(p) is a portable replacement for
25 // reinterpret_cast<T*>(p) which should be used every time address p
26 // is not guaranteed to be properly aligned to alignof(T).
27 //
28 // On architectures like x86 and ARM, where unaligned access is allowed,
29 // unaligned_cast will behave the same as reinterpret_cast and will generate
30 // the same code.
31 //
32 // Certain architectures (e.g., MIPS) make it extremely slow or outright
33 // forbidden to use ordinary machine instructions on a primitive type at an
34 // unaligned addresses - e.g., access a uint32_t at an address which is not
35 // a multiple of 4. Gcc's "undefined behavior sanitizer" (enabled in our debug
36 // build) also catches such unaligned accesses and reports them as errors,
37 // even when running on x86.
38 //
39 // Therefore, reinterpret_cast<int32_t*> on an address which is not guaranteed
40 // to be a multiple of 4 may generate extremely slow code or runtime errors,
41 // and must be avoided. The compiler needs to be told about the unaligned
42 // access, so it can generate reasonably-efficient code for the access
43 // (in MIPS, this means generating two instructions "lwl" and "lwr", instead
44 // of the one instruction "lw" which faults on unaligned/ access). The way to
45 // tell the compiler this is with __attribute__((packed)). This will also
46 // cause the sanitizer not to generate runtime alignment checks for this
47 // access.
48
49 #include <type_traits>
50
51 namespace seastar {
52
53 template <typename T>
54 struct unaligned {
55 // This is made to support only simple types, so it is fine to
56 // require them to be trivially copy constructible.
57 static_assert(std::is_trivially_copy_constructible_v<T>);
58 T raw;
59 unaligned() noexcept = default;
60 unaligned(T x) noexcept : raw(x) {}
61 unaligned& operator=(const T& x) noexcept { raw = x; return *this; }
62 operator T() const noexcept { return raw; }
63 } __attribute__((packed));
64
65
66 template <typename T, typename F>
67 [[deprecated("violates strict aliasing rules. See issue #165.")]]
68 inline auto unaligned_cast(F* p) noexcept {
69 return reinterpret_cast<unaligned<std::remove_pointer_t<T>>*>(p);
70 }
71
72 template <typename T, typename F>
73 [[deprecated("violates strict aliasing rules. See issue #165.")]]
74 inline auto unaligned_cast(const F* p) noexcept {
75 return reinterpret_cast<const unaligned<std::remove_pointer_t<T>>*>(p);
76 }
77
78 }