1
/*
2
    RawSpeed - RAW file decoder.
3

4
    Copyright (C) 2017 Roman Lebedev
5

6
    This library is free software; you can redistribute it and/or
7
    modify it under the terms of the GNU Lesser General Public
8
    License as published by the Free Software Foundation; either
9
    version 2 of the License, or (at your option) any later version.
10

11
    This library is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
    Lesser General Public License for more details.
15

16
    You should have received a copy of the GNU Lesser General Public
17
    License along with this library; if not, write to the Free Software
18
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20

21
#include "rawspeedconfig.h"
22

23
#include "common/Memory.h"
24

25
#ifndef NDEBUG
26
#include "common/Common.h" // for isPowerOfTwo, isAligned
27
#endif
28

29
#include <cassert> // for assert
30
#include <cstddef> // for size_t, uintptr_t
31

32
#if defined(HAVE_MM_MALLOC)
33
// for _mm_malloc, _mm_free
34
#include <xmmintrin.h>
35
#elif defined(HAVE_ALIGNED_MALLOC)
36
extern "C" {
37
#include <malloc.h> // for _aligned_malloc, _aligned_free
38
}
39
#else
40
#include <cstdlib> // for posix_memalign / aligned_alloc / malloc; free
41
#endif
42

43
namespace rawspeed {
44

45 2
void* alignedMalloc(size_t size, size_t alignment) {
46
  assert(isPowerOfTwo(alignment)); // for posix_memalign, _aligned_malloc
47
  assert(isAligned(alignment, sizeof(void*))); // for posix_memalign
48
  assert(isAligned(size, alignment));          // for aligned_alloc
49

50 2
  void* ptr = nullptr;
51

52
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
53
  // workaround ASAN's broken allocator_may_return_null option
54
  // plus, avoidance of libFuzzer's rss_limit_mb option
55
  // if trying to alloc more than 2GB, just return null.
56
  // else it would abort() the whole program...
57
  if (size > 2UL << 30UL)
58
    return ptr;
59
#endif
60

61
#if defined(HAVE_POSIX_MEMALIGN)
62 2
  if (0 != posix_memalign(&ptr, alignment, size))
63 0
    return nullptr;
64
#elif defined(HAVE_ALIGNED_ALLOC)
65
  ptr = aligned_alloc(alignment, size);
66
#elif defined(HAVE_MM_MALLOC)
67
  ptr = _mm_malloc(size, alignment);
68
#elif defined(HAVE_ALIGNED_MALLOC)
69
  ptr = _aligned_malloc(size, alignment);
70
#else
71
#pragma message "No aligned malloc() implementation available!"
72
  assert(alignment <= alignof(std::max_align_t));
73
#ifdef __APPLE__
74
  // apple malloc() aligns to 16 by default
75
  assert(alignment <= 16);
76
#endif
77

78
  ptr = malloc(size); // NOLINT
79
#endif
80

81
  assert(isAligned(ptr, alignment));
82

83 2
  return ptr;
84
}
85

86 2
void alignedFree(void* ptr) {
87
#if defined(HAVE_MM_MALLOC)
88
  _mm_free(ptr);
89
#elif defined(HAVE_ALIGNED_MALLOC)
90
  _aligned_free(ptr);
91
#else
92 2
  free(ptr);                    // NOLINT
93
#endif
94
}
95

96 2
void alignedFreeConstPtr(const void* ptr) {
97
// an exception, specified by EXP05-C-EX1 and EXP55-CPP-EX1
98
#if defined(HAVE_MM_MALLOC)
99
  _mm_free(const_cast<void*>(ptr));
100
#elif defined(HAVE_ALIGNED_MALLOC)
101
  _aligned_free(const_cast<void*>(ptr));
102
#else
103 2
  free(const_cast<void*>(ptr)); // NOLINT
104
#endif
105
}
106

107
} // namespace rawspeed

Read our documentation on viewing source code .

Loading