Skip to content

Commit

Permalink
Util: Add header for aligned memory allocation.
Browse files Browse the repository at this point in the history
  • Loading branch information
CrossVR committed Nov 4, 2015
1 parent 6e6fae8 commit 15b849f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 21 deletions.
75 changes: 75 additions & 0 deletions inc/osvr/Util/AlignedMemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/** @file
@brief Header defining an aligned memory allocator.
@date 2015
@author
Sensics, Inc.
<http://sensics.com/osvr>
*/

/*
// Copyright 2015 Sensics, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#ifndef INCLUDED_AlignedMemory_h_GUID_552DA92F_420A_4ADB_BCD2_493486A1C7A1
#define INCLUDED_AlignedMemory_h_GUID_552DA92F_420A_4ADB_BCD2_493486A1C7A1

// Internal Includes
// - none

// Library/third-party includes
// - none

// Standard includes
#include <memory>

#define OSVR_ALIGN_SIZE 16

namespace osvr {
namespace util {
/// @brief Aligned allocation function, gives a pointer to a block of
/// memory aligned to a memory boundary.
///
/// Used in header-only C++ wrappers over C APIs.
inline void* aligned_alloc(size_t bytes) {
// Allocate a memory buffer with enough space to store a pointer to the
// original buffer.
size_t space = bytes + OSVR_ALIGN_SIZE;
void* buffer = malloc(space + sizeof(void*));
void* aligned = (void**)buffer + 1;

// After this call the 'aligned' pointer will be aligned to a boundary.
// If there is not enough space to align the pointer, it stays unaligned.
std::align(OSVR_ALIGN_SIZE, bytes, aligned, space);

// Store the buffer pointer for the delete call.
((void **)aligned)[-1] = buffer;

return aligned;
}

/// @brief Aligned deallocation function, uses the pointer to the original
/// memory block to deallocate it.
///
/// Used in header-only C++ wrappers over C APIs.
inline void aligned_free(void* p) {
// Null-pointer should be a no-op.
if (p)
free(((void **)p)[-1]);
}
} // namespace util
} // namespace osvr
#endif // INCLUDED_AlignedMemory_h_GUID_552DA92F_420A_4ADB_BCD2_493486A1C7A1
23 changes: 2 additions & 21 deletions src/osvr/Common/ImagingComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <osvr/Common/BaseDevice.h>
#include <osvr/Common/Serialization.h>
#include <osvr/Common/Buffer.h>
#include <osvr/Util/AlignedMemory.h>
#include <osvr/Util/Flag.h>
#include <osvr/Util/Verbosity.h>

Expand All @@ -35,8 +36,6 @@
#include <sstream>
#include <utility>

#define OSVR_ALIGN_SIZE 16

namespace osvr {
namespace common {
static inline uint32_t getBufferSize(OSVR_ImagingMetadata const &meta) {
Expand Down Expand Up @@ -70,32 +69,14 @@ namespace common {

template <typename T>
void allocateBuffer(T &, size_t bytes, std::true_type const &) {
// Allocate a memory buffer with enough space to store a pointer to the
// original buffer.
size_t space = bytes + OSVR_ALIGN_SIZE;
void* buffer = malloc(space + sizeof(void*));
void* aligned = (void**)buffer + 1;

// After this call the 'aligned' pointer will be aligned to a boundary.
// If there is not enough space to align the pointer, it stays unaligned.
std::align(OSVR_ALIGN_SIZE, bytes, aligned, space);

// Store the buffer pointer for the delete call.
((void **)aligned)[-1] = buffer;

m_imgBuf.reset(reinterpret_cast<OSVR_ImageBufferElement *>(aligned), deleteBuffer);
m_imgBuf.reset(reinterpret_cast<OSVR_ImageBufferElement *>(util::aligned_alloc(bytes)), util::aligned_free);
}

template <typename T>
void allocateBuffer(T &, size_t, std::false_type const &) {
// Does nothing if we're serializing.
}

static void deleteBuffer(void* p) {
if (p)
free(((void **)p)[-1]);
}

template <typename T> void processMessage(T &p) {
process(m_meta, p);
auto bytes = getBufferSize(m_meta);
Expand Down
1 change: 1 addition & 0 deletions src/osvr/Util/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ osvr_setup_lib_vars(Util)

set(API
"${HEADER_LOCATION}/APIBaseC.h"
"${HEADER_LOCATION}/AlignedMemory.h"
"${HEADER_LOCATION}/Angles.h"
"${HEADER_LOCATION}/AnnotationMacrosC.h"
"${HEADER_LOCATION}/AnyMap.h"
Expand Down

0 comments on commit 15b849f

Please sign in to comment.