align.h
Go to the documentation of this file.
1 #ifndef __align_h__
2 #define __align_h__ 1
3 
4 #ifndef HAVE_POSIX_MEMALIGN
5 
6 #ifdef __GLIBC_PREREQ
7 #if __GLIBC_PREREQ(2,3)
8 #define HAVE_POSIX_MEMALIGN
9 #endif
10 #else
11 #ifdef _POSIX_SOURCE
12 #define HAVE_POSIX_MEMALIGN
13 #endif
14 #endif
15 
16 #endif
17 
18 #ifdef __Array_h__
19 
20 namespace Array {
21 static const array1<Complex> NULL1;
22 static const array2<Complex> NULL2;
23 static const array3<Complex> NULL3;
24 }
25 
26 #else
27 
28 #ifdef HAVE_POSIX_MEMALIGN
29 #ifdef _AIX
30 extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size);
31 #endif
32 #else
33 namespace Array {
34 
35 // Adapted from FFTW aligned malloc/free. Assumes that malloc is at least
36 // sizeof(void*)-aligned. Allocated memory must be freed with free0.
37 inline int posix_memalign0(void **memptr, size_t alignment, size_t size)
38 {
39  if(alignment % sizeof (void *) != 0 || (alignment & (alignment - 1)) != 0)
40  return EINVAL;
41  void *p0=malloc(size+alignment);
42  if(!p0) return ENOMEM;
43  void *p=(void *)(((size_t) p0+alignment)&~(alignment-1));
44  *((void **) p-1)=p0;
45  *memptr=p;
46  return 0;
47 }
48 
49 inline void free0(void *p)
50 {
51  if(p) free(*((void **) p-1));
52 }
53 
54 }
55 #endif
56 
57 namespace Array {
58 
59 template<class T>
60 inline void newAlign(T *&v, size_t len, size_t align)
61 {
62  void *mem=NULL;
63  const char *invalid="Invalid alignment requested";
64  const char *nomem="Memory limits exceeded";
65 #ifdef HAVE_POSIX_MEMALIGN
66  int rc=posix_memalign(&mem,align,len*sizeof(T));
67 #else
68  int rc=posix_memalign0(&mem,align,len*sizeof(T));
69 #endif
70  if(rc == EINVAL) std::cerr << invalid << std::endl;
71  if(rc == ENOMEM) std::cerr << nomem << std::endl;
72  v=(T *) mem;
73  for(size_t i=0; i < len; i++) new(v+i) T;
74 }
75 
76 template<class T>
77 inline void deleteAlign(T *v, size_t len)
78 {
79  for(size_t i=len; i-- > 0;) v[i].~T();
80 #ifdef HAVE_POSIX_MEMALIGN
81  free(v);
82 #else
83  free0(v);
84 #endif
85 }
86 }
87 
88 #endif
89 
90 namespace utils {
91 
92 inline unsigned int ceilquotient(unsigned int a, unsigned int b)
93 {
94  return (a+b-1)/b;
95 }
96 
97 inline Complex *ComplexAlign(size_t size)
98 {
99  Complex *v;
100  Array::newAlign(v,size,sizeof(Complex));
101  return v;
102 }
103 
104 inline double *doubleAlign(size_t size)
105 {
106  double *v;
107  Array::newAlign(v,size,sizeof(Complex));
108  return v;
109 }
110 
111 template<class T>
112 inline void deleteAlign(T *p)
113 {
114 #ifdef HAVE_POSIX_MEMALIGN
115  free(p);
116 #else
117  Array::free0(p);
118 #endif
119 }
120 
121 }
122 
123 #endif
void deleteAlign(T *p)
Definition: align.h:112
unsigned int ceilquotient(unsigned int a, unsigned int b)
Definition: align.h:92
std::complex< double > Complex
Definition: fftw++.h:83
int posix_memalign0(void **memptr, size_t alignment, size_t size)
Definition: align.h:37
void newAlign(T *&v, size_t len, size_t align)
Definition: align.h:60
void free0(void *p)
Definition: align.h:49
Complex * ComplexAlign(size_t size)
Definition: align.h:97
double * doubleAlign(size_t size)
Definition: align.h:104
TabulatedPDF::Array Array
Definition: TabulatedPDF.cc:15
void deleteAlign(T *v, size_t len)
Definition: align.h:77

, generated on Tue Sep 26 2023.