blob: 2f59b789ed42f94b36795d955b3cfa6366822fbd [file] [log] [blame]
Brian Silvermana1652f32020-01-29 20:41:44 -08001#ifndef AOS_IPC_LIB_DATA_ALIGNMENT_H_
2#define AOS_IPC_LIB_DATA_ALIGNMENT_H_
3
4#include "glog/logging.h"
5
6namespace aos {
7
8// All data buffers sent over or received from a channel will guarantee this
9// alignment for their end. Flatbuffers aligns from the end, so this is what
10// matters.
11//
12// 64 is a reasonable choice for now:
13// Cortex-A72 (Raspberry Pi 4) and Cortex-A53 (Xavier AGX) both have 64 byte
14// cache lines.
15// V4L2 requires 64 byte alignment for USERPTR buffers.
16static constexpr size_t kChannelDataAlignment = 64;
17
18template <typename T>
19inline void CheckChannelDataAlignment(T *data, size_t size) {
20 CHECK_EQ((reinterpret_cast<uintptr_t>(data) + size) % kChannelDataAlignment,
21 0u)
22 << ": data pointer is not end aligned as it should be: " << data << " + "
23 << size;
24}
25
26// Aligns the beginning of a channel data buffer. There must be
27// kChannelDataAlignment-1 extra bytes beyond the end to potentially use after
28// aligning it.
29inline char *RoundChannelData(char *data, size_t size) {
30 const uintptr_t data_value = reinterpret_cast<uintptr_t>(data);
31 const uintptr_t data_end = data_value + size;
32 const uintptr_t data_end_max = data_end + (kChannelDataAlignment - 1);
33 const uintptr_t rounded_data_end =
34 data_end_max - (data_end_max % kChannelDataAlignment);
35 const uintptr_t rounded_data = rounded_data_end - size;
36 return reinterpret_cast<char *>(rounded_data);
37}
38
39} // namespace aos
40
41#endif // AOS_IPC_LIB_DATA_ALIGNMENT_H_