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@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 18void 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 30void 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 42void 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 54void 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... 67struct MyStruct 68{ 69 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 70 char dummychar; 71 Vector4f avec; 72}; 73 74class MyClassA 75{ 76 public: 77 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 78 char dummychar; 79 Vector4f avec; 80}; 81 82template<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 90void 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