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 < 400; 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(T::NeedsToAlign==1); 86 VERIFY(size_t(obj)%ALIGNMENT==0); 87 delete obj; 88 } 89 90 void test_dynalloc() 91 { 92 // low level dynamic memory allocation 93 CALL_SUBTEST(check_handmade_aligned_malloc()); 94 CALL_SUBTEST(check_aligned_malloc()); 95 CALL_SUBTEST(check_aligned_new()); 96 CALL_SUBTEST(check_aligned_stack_alloc()); 97 98 for (int i=0; i<g_repeat*100; ++i) 99 { 100 CALL_SUBTEST(check_dynaligned<Vector4f>() ); 101 CALL_SUBTEST(check_dynaligned<Vector2d>() ); 102 CALL_SUBTEST(check_dynaligned<Matrix4f>() ); 103 CALL_SUBTEST(check_dynaligned<Vector4d>() ); 104 CALL_SUBTEST(check_dynaligned<Vector4i>() ); 105 } 106 107 // check static allocation, who knows ? 108 #if EIGEN_ALIGN_STATICALLY 109 { 110 MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0); 111 MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0); 112 } 113 114 // dynamic allocation, single object 115 for (int i=0; i<g_repeat*100; ++i) 116 { 117 MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0); 118 MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0); 119 delete foo0; 120 delete fooA; 121 } 122 123 // dynamic allocation, array 124 const int N = 10; 125 for (int i=0; i<g_repeat*100; ++i) 126 { 127 MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0); 128 MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0); 129 delete[] foo0; 130 delete[] fooA; 131 } 132 #endif 133 134 } 135