AlignedAllocator.cpp 2.51 KB
Newer Older
1
// The following headers are required for all allocators.
mvalle's avatar
mvalle committed
2
#include <cstddef>  // Required for size_t and ptrdiff_t and NULL
3
4
5
#include <stdexcept> // Required for std::length_error

// The following headers contain stuff that AlignedAllocator uses.
mvalle's avatar
mvalle committed
6
7
8
#include <cstdlib>  // For malloc() and free()

// For XMT the following function should be supplied till the bug is fixed by Cray
9
10
11
12
13
14
15
16
#ifdef __MTA__
//extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size);
static int posix_memalign(void **memptr, size_t alignment, size_t size)
{
	*memptr = malloc(size);
	return 0;
}
#endif
17
18
19
20

#include "AlignedMalloc.h"

#ifndef _MSC_VER
21
//#include <stdint.h>  // for uintptr_t
22
#include <malloc.h>
23
24
25
#endif

// Alignment must be power of 2 (1,2,4,8,16...)
26
void* alignedMalloc(size_t aSize, size_t aAlignment)
27
{
mvalle's avatar
mvalle committed
28
#ifdef _MSC_VER
29
#if 0
30
31
	--aAlignment;
    uintptr_t r = reinterpret_cast<uintptr_t>(malloc(aSize + aAlignment + sizeof(uintptr_t)));
32
    if(!r) return NULL;
33
34
    uintptr_t t = r + sizeof(uintptr_t);
    uintptr_t o = (t + aAlignment) & ~static_cast<uintptr_t>(aAlignment);
mvalle's avatar
mvalle committed
35
36
    reinterpret_cast<uintptr_t*>(o)[-1] = r;
    return reinterpret_cast<void*>(o);
37
38
#endif
	return _aligned_malloc(aSize, aAlignment);
39
#else
mvalle's avatar
mvalle committed
40
41
	void* ptr = NULL;
	if(posix_memalign(&ptr, aAlignment, aSize)) return NULL;
42
43
	return ptr;
#endif
44
45
}

46
void alignedFree(void* aPtr)
47
{
48
    if(!aPtr) return;
mvalle's avatar
mvalle committed
49
#ifdef _MSC_VER
50
#if 0
51
    free(reinterpret_cast<void*>(reinterpret_cast<uintptr_t*>(aPtr)[-1]));
52
53
#endif
	_aligned_free(aPtr);
54
55
56
#else
    free(aPtr);
#endif
57
58
59
60
}


#if 0
mvalle's avatar
mvalle committed
61
62

// The following headers contain stuff that main() uses.
63
#include <iostream>  // For std::cout
mvalle's avatar
mvalle committed
64
65
#include <ostream>   // For std::endl
#include <vector>    // For std::vector
mvalle's avatar
mvalle committed
66
#include "AlignedAllocator.h"
mvalle's avatar
mvalle committed
67

68
69
70
71
int main()
{
    using namespace std;

72
    cout << "Constructing l:" << endl;
73
74
75

    vector<double, AlignedAllocator<double, 8> > l;
	l.reserve(10);
76
    cout << endl << "l.push_back(1729):" << endl;
77
78
79

    l.push_back(1729.);

80
    cout << endl << "l.push_back(2161):" << endl;
81
82
83

    l.push_back(2161.);

84
    cout << endl;
85
86
	double* p = &l[0];
	int x = reinterpret_cast<int>(p);
87
88
89
90
	cout << "Aligned on 16: " << x%16 << endl;
	cout << "Aligned on 8:  " << x%8 << endl;
	cout << "Aligned on 4:  " << x%4 << endl;
    cout << endl;
91
92

    for (vector<double, AlignedAllocator<double, 8> >::const_iterator i = l.begin(); i != l.end(); ++i) {
93
        cout << "Element: " << *i << endl;
94
95
    }

96
    cout << endl << "Destroying l:" << endl;
97
98
99
}
#endif