NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
aligned_new.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 #ifndef APPLICATIONS_STORAGE_STORAGE_COMMON_ALIGNED_NEW_HPP_
26 #define APPLICATIONS_STORAGE_STORAGE_COMMON_ALIGNED_NEW_HPP_
27 
28 #include <algorithm>
29 #include <cstddef>
30 #include <cstdlib>
31 #include <stdexcept>
32 #include <type_traits>
33 
34 namespace storage {
35 
36 template <typename T>
37 class make_aligned {
38 public:
39  make_aligned<T> &aligned_to(size_t alignment)
40  {
41  if (alignment < std::alignment_of<T>::value) {
42  throw std::logic_error{
43  "Specified alignment must be at least the natural alignment of the object"};
44  }
45 
46  if ((alignment % std::alignment_of<T>::value) != 0) {
47  throw std::logic_error{
48  "Specified alignment must be a multiple the natural alignment of the object"};
49  }
50 
51  m_alignment = alignment;
52 
53  return *this;
54  }
55 
56  /*
57  * Create a single aligned object
58  *
59  * @args [in]: variadic argument list to be forwarded to the constructor of T
60  * @return: Pointer to aligned object
61  */
62  template <typename... Args>
63  T *object(Args &&...args) const
64  {
65  auto *storage = static_cast<T *>(aligned_alloc(m_alignment, sizeof(T)));
66  if (storage == nullptr) {
67  throw std::bad_alloc{};
68  }
69 
70  try {
71  static_cast<void>(new (storage) T{std::forward<Args>(args)...});
72  } catch (...) {
73  free(storage);
74  throw;
75  }
76 
77  return storage;
78  }
79 
80  /*
81  * Create an array of aligned objects
82  *
83  * @object_count [in]: Number of objects to create in the array
84  * @args [in]: variadic argument list to be forwarded to the constructor of T
85  * @return: Pointer to aligned object
86  */
87  template <typename... Args>
88  T *object_array(size_t object_count, Args &&...args) const
89  {
90  auto *storage = static_cast<T *>(aligned_alloc(m_alignment, sizeof(T) * object_count));
91  if (storage == nullptr) {
92  throw std::bad_alloc{};
93  }
94 
95  size_t valid_count = 0;
96  try {
97  for (size_t ii = 0; ii != object_count; ++ii) {
98  static_cast<void>(new (std::addressof(storage[ii])) T{args...});
99  ++valid_count;
100  }
101  } catch (...) {
102  while (valid_count) {
103  storage[--valid_count].~T();
104  }
105 
106  free(storage);
107  throw;
108  }
109 
110  return storage;
111  }
112 
113 private:
114  size_t m_alignment = std::alignment_of<T>::value;
115 };
116 
117 } // namespace storage
118 
119 #endif // APPLICATIONS_STORAGE_STORAGE_COMMON_ALIGNED_NEW_HPP_
make_aligned< T > & aligned_to(size_t alignment)
Definition: aligned_new.hpp:39
T * object_array(size_t object_count, Args &&...args) const
Definition: aligned_new.hpp:88
T * object(Args &&...args) const
Definition: aligned_new.hpp:63
type value
void * aligned_alloc(size_t alignment, size_t size)
Definition: os_utils.cpp:126