1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud (at) inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #include "main.h" 11 12 #if EIGEN_ALIGN 13 #define ALIGNMENT 16 14 #else 15 #define ALIGNMENT 1 16 #endif 17 18 void check_handmade_aligned_malloc() 19 { 20 for(int i = 1; i < 1000; i++) 21 { 22 char *p = (char*)internal::handmade_aligned_malloc(i); 23 VERIFY(size_t(p)%ALIGNMENT==0); 24 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 25 for(int j = 0; j < i; j++) p[j]=0; 26 internal::handmade_aligned_free(p); 27 } 28 } 29 30 void check_aligned_malloc() 31 { 32 for(int i = 1; i < 1000; i++) 33 { 34 char *p = (char*)internal::aligned_malloc(i); 35 VERIFY(size_t(p)%ALIGNMENT==0); 36 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 37 for(int j = 0; j < i; j++) p[j]=0; 38 internal::aligned_free(p); 39 } 40 } 41 42 void check_aligned_new() 43 { 44 for(int i = 1; i < 1000; i++) 45 { 46 float *p = internal::aligned_new<float>(i); 47 VERIFY(size_t(p)%ALIGNMENT==0); 48 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 49 for(int j = 0; j < i; j++) p[j]=0; 50 internal::aligned_delete(p,i); 51 } 52 } 53 54 void check_aligned_stack_alloc() 55 { 56 for(int i = 1; i < 1000; i++) 57 { 58 ei_declare_aligned_stack_constructed_variable(float,p,i,0); 59 VERIFY(size_t(p)%ALIGNMENT==0); 60 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 61 for(int j = 0; j < i; j++) p[j]=0; 62 } 63 } 64 65 66 // test compilation with both a struct and a class... 67 struct MyStruct 68 { 69 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 70 char dummychar; 71 Vector4f avec; 72 }; 73 74 class MyClassA 75 { 76 public: 77 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 78 char dummychar; 79 Vector4f avec; 80 }; 81 82 template<typename T> void check_dynaligned() 83 { 84 T* obj = new T; 85 VERIFY(size_t(obj)%ALIGNMENT==0); 86 delete obj; 87 } 88 89 void test_dynalloc() 90 { 91 // low level dynamic memory allocation 92 CALL_SUBTEST(check_handmade_aligned_malloc()); 93 CALL_SUBTEST(check_aligned_malloc()); 94 CALL_SUBTEST(check_aligned_new()); 95 CALL_SUBTEST(check_aligned_stack_alloc()); 96 97 for (int i=0; i<g_repeat*100; ++i) 98 { 99 CALL_SUBTEST(check_dynaligned<Vector4f>() ); 100 CALL_SUBTEST(check_dynaligned<Vector2d>() ); 101 CALL_SUBTEST(check_dynaligned<Matrix4f>() ); 102 CALL_SUBTEST(check_dynaligned<Vector4d>() ); 103 CALL_SUBTEST(check_dynaligned<Vector4i>() ); 104 } 105 106 // check static allocation, who knows ? 107 #if EIGEN_ALIGN_STATICALLY 108 { 109 MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0); 110 MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0); 111 } 112 113 // dynamic allocation, single object 114 for (int i=0; i<g_repeat*100; ++i) 115 { 116 MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0); 117 MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0); 118 delete foo0; 119 delete fooA; 120 } 121 122 // dynamic allocation, array 123 const int N = 10; 124 for (int i=0; i<g_repeat*100; ++i) 125 { 126 MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0); 127 MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0); 128 delete[] foo0; 129 delete[] fooA; 130 } 131 #endif 132 133 } 134