1 /*
2 * Copyright (C) 2009-2016 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2015 Robin Gareus <robin@gareus.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "libpbd-config.h"
21
22 #include <cstring>
23 #include <cerrno>
24
25 #include "pbd/malign.h"
26 #include "pbd/error.h"
27
28 #include "pbd/i18n.h"
29
30 using namespace PBD;
31
32 #if ( defined(__x86_64__) || defined(_M_X64) )
33 static const int CPU_CACHE_ALIGN = 64;
34 #elif defined ARM_NEON_SUPPORT
35 static const int CPU_CACHE_ALIGN = 128; // sizeof(float32x4_t)
36 #else
37 static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */
38 #endif
39
cache_aligned_malloc(void ** memptr,size_t size)40 int cache_aligned_malloc (void** memptr, size_t size)
41 {
42 #ifndef HAVE_POSIX_MEMALIGN
43 #ifdef PLATFORM_WINDOWS
44 if (((*memptr) = _aligned_malloc (size, CPU_CACHE_ALIGN)) == 0) {
45 fatal << string_compose (_("Memory allocation error: malloc (%1 * %2) failed (%3)"),
46 CPU_CACHE_ALIGN, size, strerror (errno)) << endmsg;
47 return errno;
48 } else {
49 return 0;
50 }
51 #else
52 if (((*memptr) = malloc (size)) == 0) {
53 fatal << string_compose (_("Memory allocation error: malloc (%1 * %2) failed (%3)"),
54 CPU_CACHE_ALIGN, size, strerror (errno)) << endmsg;
55 return errno;
56 } else {
57 return 0;
58 }
59 #endif
60 #else
61 if (posix_memalign (memptr, CPU_CACHE_ALIGN, size)) {
62 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
63 CPU_CACHE_ALIGN, size, strerror (errno)) << endmsg;
64 }
65
66 return 0;
67 #endif
68 }
69
cache_aligned_free(void * memptr)70 void cache_aligned_free (void* memptr)
71 {
72 #ifdef PLATFORM_WINDOWS
73 _aligned_free (memptr);
74 #else
75 free (memptr);
76 #endif
77 }
78
aligned_malloc(void ** memptr,size_t size,size_t alignment)79 int aligned_malloc (void** memptr, size_t size, size_t alignment)
80 {
81 #ifndef HAVE_POSIX_MEMALIGN
82 #ifdef PLATFORM_WINDOWS
83 if (((*memptr) = _aligned_malloc (size, alignment)) == 0) {
84 fatal << string_compose (_("Memory allocation error: malloc (%1 * %2) failed (%3)"),
85 alignment, size, strerror (errno)) << endmsg;
86 return errno;
87 } else {
88 return 0;
89 }
90 #else
91 if (((*memptr) = malloc (size)) == 0) {
92 fatal << string_compose (_("Memory allocation error: malloc (%1 * %2) failed (%3)"),
93 alignment, size, strerror (errno)) << endmsg;
94 return errno;
95 } else {
96 return 0;
97 }
98 #endif
99 #else
100 if (posix_memalign (memptr, alignment, size)) {
101 fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"),
102 alignment, size, strerror (errno)) << endmsg;
103 }
104
105 return 0;
106 #endif
107 }
108
aligned_free(void * memptr)109 void aligned_free (void* memptr)
110 {
111 #ifdef PLATFORM_WINDOWS
112 _aligned_free (memptr);
113 #else
114 free (memptr);
115 #endif
116 }
117