diff --git a/src/util.cc b/src/util.cc index b3ae1c6858..171dc79754 100644 --- a/src/util.cc +++ b/src/util.cc @@ -2187,6 +2187,57 @@ void safe_close(int fd) } } +const void* memory_align(const void* ptr, size_t size) + { + if ( ! size ) + return ptr; + + ASSERT(is_power_of_2(size)); + + const char* buf = reinterpret_cast(ptr); + size_t mask = size - 1; // Assume size is a power of 2. + unsigned long l_ptr = reinterpret_cast(ptr); + unsigned long offset = l_ptr & mask; + + if ( offset > 0 ) + return reinterpret_cast(buf - offset + size); + else + return reinterpret_cast(buf); + } + +void* memory_align_and_pad(void* ptr, size_t size) + { + if ( ! size ) + return ptr; + + ASSERT(is_power_of_2(size)); + + char* buf = reinterpret_cast(ptr); + size_t mask = size - 1; + while ( (reinterpret_cast(buf) & mask) != 0 ) + // Not aligned - zero pad. + *buf++ = '\0'; + + return reinterpret_cast(buf); + } + +int memory_size_align(size_t offset, size_t size) + { + if ( ! size || ! offset ) + return offset; + + ASSERT(is_power_of_2(size)); + + size_t mask = size - 1; // Assume size is a power of 2. + if ( offset & mask ) + { + offset &= ~mask; // Round down. + offset += size; // Round up. + } + + return offset; + } + void get_memory_usage(uint64_t* total, uint64_t* malloced) { uint64_t ret_total; diff --git a/src/util.h b/src/util.h index 3647c179ef..039e9fdd81 100644 --- a/src/util.h +++ b/src/util.h @@ -493,6 +493,24 @@ inline char* safe_strncpy(char* dest, const char* src, size_t n) return result; } +// Memory alignment helpers. + +inline bool is_power_of_2(bro_uint_t x) + { + return ((x - 1) & x) == 0; + } + +// Rounds the given pointer up to the nearest multiple of the +// given size, if not already a multiple. +const void* memory_align(const void* ptr, size_t size); + +// Rounds the given pointer up to the nearest multiple of the +// given size, padding the skipped region with 0 bytes. +void* memory_align_and_pad(void* ptr, size_t size); + +// Returns offset rounded up so it can correctly align data of the given size. +int memory_size_align(size_t offset, size_t size); + // Returns total memory allocations and (if available) amount actually // handed out by malloc. extern void get_memory_usage(uint64_t* total, uint64_t* malloced);