128 lines
2.6 KiB
C++
128 lines
2.6 KiB
C++
/*
|
|
* aligned_mem.h
|
|
*
|
|
* Created on: May 14, 2013
|
|
* Author: cforster
|
|
*
|
|
* Code from libcvd: cvd/internal/aligned_mem.h
|
|
* https://github.com/edrosten/libcvd
|
|
* Licence: LGPL 2.1
|
|
*/
|
|
|
|
#ifndef VIKIT_ALIGNED_MEM_H_
|
|
#define VIKIT_ALIGNED_MEM_H_
|
|
|
|
#include <string> // memset
|
|
#include <string.h> // memset
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
|
|
namespace vk {
|
|
namespace aligned_mem {
|
|
|
|
/// Check if the pointer is aligned to the specified byte granularity
|
|
inline bool
|
|
is_aligned8(const void* ptr)
|
|
{
|
|
return ((reinterpret_cast<size_t>(ptr)) & 0x7) == 0;
|
|
}
|
|
|
|
inline bool
|
|
is_aligned16(const void* ptr)
|
|
{
|
|
return ((reinterpret_cast<size_t>(ptr)) & 0xF) == 0;
|
|
}
|
|
|
|
template <class T, int N=20> struct placement_delete
|
|
{
|
|
enum { Size = (1<<N) };
|
|
|
|
struct Array {
|
|
T data[Size];
|
|
};
|
|
|
|
static inline void destruct(T* buf)
|
|
{
|
|
(*(Array*)buf).~Array();
|
|
}
|
|
|
|
static inline void free(T* buf, size_t M)
|
|
{
|
|
if (M >= Size) {
|
|
placement_delete<T,N>::free(buf+Size,M-Size);
|
|
placement_delete<T,N>::destruct(buf);
|
|
} else {
|
|
placement_delete<T,N-1>::free(buf, M);
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class T> struct placement_delete<T,-1>
|
|
{
|
|
static inline void free(T*, size_t ) {}
|
|
};
|
|
|
|
inline void * aligned_alloc(size_t count, size_t alignment){
|
|
void * mem = NULL;
|
|
assert(posix_memalign(&mem, alignment, count) == 0);
|
|
return mem;
|
|
}
|
|
|
|
inline void aligned_free(void * memory) {
|
|
free(memory);
|
|
}
|
|
|
|
template <class T>
|
|
inline T * aligned_alloc(size_t count, size_t alignment){
|
|
void * data = aligned_alloc(sizeof(T)* count, alignment);
|
|
return new (data) T[count];
|
|
}
|
|
|
|
template <class T>
|
|
inline void aligned_free(T * memory, size_t count){
|
|
placement_delete<T>::free(memory, count);
|
|
aligned_free(memory);
|
|
}
|
|
|
|
template<class T> inline void memfill(T* data, int n, const T val)
|
|
{
|
|
T* de = data + n;
|
|
for(;data < de; data++)
|
|
*data=val;
|
|
}
|
|
|
|
template<> inline void memfill(unsigned char* data, int n, const unsigned char val)
|
|
{
|
|
memset(data, val, n);
|
|
}
|
|
|
|
template<> inline void memfill(signed char* data, int n, const signed char val)
|
|
{
|
|
memset(data, val, n);
|
|
}
|
|
|
|
template<> inline void memfill(char* data, int n, const char val)
|
|
{
|
|
memset(data, val, n);
|
|
}
|
|
|
|
template <class T, int N>
|
|
struct AlignedMem {
|
|
T* mem;
|
|
size_t count;
|
|
AlignedMem(size_t c) : count(c) {
|
|
mem = aligned_alloc<T>(count, N);
|
|
}
|
|
~AlignedMem() {
|
|
aligned_free<T>(mem, count);
|
|
}
|
|
T* data() { return mem; }
|
|
const T* data() const { return mem; }
|
|
};
|
|
|
|
} // namespace aligned_mem
|
|
} // namespace vikit
|
|
|
|
|
|
#endif // VIKIT_ALIGNED_MEM_H_
|