blob: 9cbfa23b8aa13f2b961d4e131ce7ff61bef15351 [file] [log] [blame]
#ifndef AOS_IPC_LIB_DATA_ALIGNMENT_H_
#define AOS_IPC_LIB_DATA_ALIGNMENT_H_
#include "absl/log/check.h"
#include "absl/log/log.h"
namespace aos {
// All data buffers sent over or received from a channel will guarantee this
// alignment for their end. Flatbuffers aligns from the end, so this is what
// matters.
//
// 128 is a reasonable choice for now:
// Cortex-A72 (Raspberry Pi 4) and Cortex-A53 (Xavier AGX) both have 64 byte
// cache lines.
// V4L2 requires 64 byte alignment for USERPTR buffers.
//
// rockpi v4l2 requires 128 byte alignment for USERPTR buffers.
static constexpr size_t kChannelDataAlignment = 128;
template <typename T>
inline void CheckChannelDataAlignment(T *data, size_t size) {
CHECK_EQ((reinterpret_cast<uintptr_t>(data) + size) % kChannelDataAlignment,
0u)
<< ": data pointer is not end aligned as it should be: " << data << " + "
<< size;
}
// Aligns the beginning of a channel data buffer. There must be
// kChannelDataAlignment-1 extra bytes beyond the end to potentially use after
// aligning it.
inline char *RoundChannelData(char *data, size_t size) {
const uintptr_t data_value = reinterpret_cast<uintptr_t>(data);
const uintptr_t data_end = data_value + size;
const uintptr_t data_end_max = data_end + (kChannelDataAlignment - 1);
const uintptr_t rounded_data_end =
data_end_max - (data_end_max % kChannelDataAlignment);
const uintptr_t rounded_data = rounded_data_end - size;
return reinterpret_cast<char *>(rounded_data);
}
// The size of the redzone we maintain outside each message's data to help
// detect out-of-bounds writes.
static constexpr size_t kChannelDataRedzone = 32;
} // namespace aos
#endif // AOS_IPC_LIB_DATA_ALIGNMENT_H_