rambrain
testManagedPtr.cpp
Go to the documentation of this file.
1 /* rambrain - a dynamical physical memory extender
2  * Copyright (C) 2015 M. Imgrund, A. Arth
3  * mimgrund (at) mpifr-bonn.mpg.de
4  * arth (at) usm.uni-muenchen.de
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "tester.h"
22 
23 #include <gtest/gtest.h>
24 #include "managedPtr.h"
25 #include "cyclicManagedMemory.h"
26 #include "managedDummySwap.h"
27 #include "dummyManagedMemory.h"
28 #include "exceptions.h"
29 
30 #ifndef OpenMP_NOT_FOUND
31 #include <omp.h>
32 #endif
33 
34 using namespace rambrain;
35 
39 TEST ( managedPtr, Unit_NoMemoryManager )
40 {
41  EXPECT_NO_THROW ( managedPtr<double> ptr1 ( 10 ) );
42 
43  managedDummySwap swap ( 100 );
44  cyclicManagedMemory managedMemory ( &swap, 100 );
45 
46  ASSERT_NO_THROW ( managedPtr<double> ptr2 ( 10 ) );
47 }
48 
49 
50 #ifdef PARENTAL_CONTROL
51 
54 TEST ( managedPtr, Unit_ParentIDs )
55 {
56  managedDummySwap swap ( 100 );
57  cyclicManagedMemory managedMemory ( &swap, 100 );
59 
60  ASSERT_NO_THROW ( managedPtr<double> ptr ( 10 ) );
61  EXPECT_EQ ( parent, managedMemory::defaultManager->parent );
62 }
63 #endif
64 
65 
69 TEST ( managedPtr, Unit_ChunkInUse )
70 {
71  managedDummySwap swap ( 100 );
72  cyclicManagedMemory managedMemory ( &swap, 100 );
73  managedPtr<double> ptr ( 10 );
74 
75  ASSERT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
76 
77  ptr.setUse();
78 
79  ASSERT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
80 
81  ptr.unsetUse();
82 
83  ASSERT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
84 
85  ptr.setUse ( true );
86 
87  ASSERT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
88 
89  ptr.unsetUse();
90 
91  ASSERT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
92 
93  ptr.setUse ( false );
94 
95  ASSERT_EQ ( MEM_ALLOCATED_INUSE_READ, ptr.chunk->status );
96 
97  ptr.unsetUse();
98 }
99 
100 
104 TEST ( managedPtr, Unit_GetLocPointer )
105 {
106  managedDummySwap swap ( 100 );
107  cyclicManagedMemory managedMemory ( &swap, 100 );
108  managedMemory.setPreemptiveUnloading ( false );
109 
110  managedPtr<double> ptr ( 10 );
111 
112  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
113 
114  ptr.setUse();
115 
116  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
117  EXPECT_NO_THROW ( ptr.getLocPtr() );
118 
119  ptr.unsetUse();
120 
121  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
122 }
123 
124 
128 TEST ( managedPtr, Unit_SmartPointery )
129 {
130  managedDummySwap swap ( 200 );
131  cyclicManagedMemory managedMemory ( &swap, 200 );
132 
133  managedPtr<double> ptr ( 5 );
134  for ( int n = 0; n < 5; n++ ) {
135  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
136 
137  ADHERETOLOC ( double, ptr, lptr );
138  lptr[n] = n;
139 
140  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
141  }
142  managedPtr<double> ptr2 ( 5 );
143  for ( int n = 0; n < 5; n++ ) {
144  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
145  EXPECT_EQ ( MEM_ALLOCATED, ptr2.chunk->status );
146 
147  ADHERETOLOC ( double, ptr, lptr );
148  ADHERETOLOC ( double, ptr2, lptr2 );
149  lptr2[n] = 1 - n;
150 
151  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
152  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr2.chunk->status );
153  }
154 
155  EXPECT_EQ ( 5 * sizeof ( double ) * 2, managedMemory.getUsedMemory() );
156  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
157  EXPECT_EQ ( MEM_ALLOCATED, ptr2.chunk->status );
158 
159  ptr = ptr2;
160 
161  EXPECT_EQ ( 5 * sizeof ( double ), managedMemory.getUsedMemory() );
162  EXPECT_EQ ( MEM_ALLOCATED, ptr.chunk->status );
163  EXPECT_EQ ( MEM_ALLOCATED, ptr2.chunk->status );
164 
165  for ( int n = 0; n < 5; n++ ) {
166  ADHERETOLOCCONST ( double, ptr, lptr );
167  ADHERETOLOCCONST ( double, ptr2, lptr2 );
168 
169  EXPECT_EQ ( 1 - n, lptr[n] );
170  EXPECT_EQ ( 1 - n, lptr2[n] );
171  EXPECT_EQ ( MEM_ALLOCATED_INUSE_READ, ptr.chunk->status );
172  EXPECT_EQ ( MEM_ALLOCATED_INUSE_READ, ptr2.chunk->status );
173  }
174 
175  ptr = ptr2;
176 
177  for ( int n = 0; n < 5; n++ ) {
178  ADHERETOLOC ( double, ptr, lptr );
179  ADHERETOLOC ( double, ptr2, lptr2 );
180 
181  EXPECT_EQ ( 1 - n, lptr[n] );
182  EXPECT_EQ ( 1 - n, lptr2[n] );
183  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
184  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr2.chunk->status );
185  }
186  ptr = ptr;
187  for ( int n = 0; n < 5; n++ ) {
188  ADHERETOLOCCONST ( double, ptr, lptr );
189  ADHERETOLOCCONST ( double, ptr2, lptr2 );
190 
191  EXPECT_EQ ( 1 - n, lptr[n] );
192  EXPECT_EQ ( 1 - n, lptr2[n] );
193  EXPECT_EQ ( MEM_ALLOCATED_INUSE_READ, ptr.chunk->status );
194  EXPECT_EQ ( MEM_ALLOCATED_INUSE_READ, ptr2.chunk->status );
195  }
196  managedPtr<double> ptr3 ( ptr );
197  for ( int n = 0; n < 5; n++ ) {
198  ADHERETOLOC ( double, ptr, lptr );
199  ADHERETOLOC ( double, ptr2, lptr2 );
200  ADHERETOLOC ( double, ptr3, lptr3 );
201 
202  EXPECT_EQ ( 1 - n, lptr[n] );
203  EXPECT_EQ ( 1 - n, lptr2[n] );
204  EXPECT_EQ ( 1 - n, lptr3[n] );
205  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr.chunk->status );
206  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr2.chunk->status );
207  EXPECT_EQ ( MEM_ALLOCATED_INUSE_WRITE, ptr3.chunk->status );
208  }
209 }
210 
211 
215 TEST ( managedPtr, Unit_DeleteWhileInUse )
216 {
217  /*
218  * Idea: Death test, do we want to let everything die at this point?
219  * Ideally, we are not allowed to throw in a destructor. Doing it anyways terminates programm
220  */
221  managedDummySwap swap ( 100 );
222  //The following test will shoot its manager. To reenact the old one, lets save its pointer:
224 
226  managedPtr<double> *ptr = new managedPtr<double> ( 10 );
227  ptr->setUse();
228 
229  ASSERT_DEATH ( delete ptr, "terminate called after throwing an instance of 'rambrain::memoryException'" );
230  printf ( "Hello from below" );
231 
232  //We would like to call the destructor of managedMemory, however this destructor will segfault because of the death test...
233  //Thus, only get the old one back again:
235 }
236 
237 
241 TEST ( managedPtr, Unit_DirectAccess )
242 {
243  managedDummySwap swap ( 200 );
244  cyclicManagedMemory managedMemory ( &swap, 200 );
245 
246  managedPtr<double> ptr ( 5 );
247  for ( int n = 0; n < 5; n++ ) {
248  ptr[n] = n;
249  }
250 
251  for ( int n = 0; n < 5; n++ ) {
252  EXPECT_EQ ( n, ptr[n] );
253  }
254 }
255 
256 
260 TEST ( managedPtr, Unit_DirectAccessSwapped )
261 {
262  const unsigned int alloc = 10u;
263  const unsigned int memsize = 1.5 * alloc * sizeof ( double );
264  const unsigned int swapsize = 10 * memsize;
265 
266  managedDummySwap swap ( swapsize );
267  cyclicManagedMemory managedMemory ( &swap, memsize );
268 
269  managedPtr<double> ptr1 ( alloc );
270  managedPtr<double> ptr2 ( alloc );
271  for ( unsigned int n = 0; n < alloc; n++ ) {
272  ptr1[n] = n;
273  ptr2[n] = 2 * n;
274  }
275 
276  for ( unsigned int n = 0; n < alloc; n++ ) {
277  EXPECT_EQ ( n, ptr1[n] );
278  EXPECT_EQ ( 2 * n, ptr2[n] );
279  }
280 }
281 
282 
286 TEST ( managedPtr, Unit_CreateAndInitialize )
287 {
288 
289  class nurfuerspassclass
290  {
291  public:
292  nurfuerspassclass ( int a ) : val ( a ) {};
293  int val;
294  };
295 
296  const unsigned int alloc = 10u;
297  const unsigned int memsize = 1.5 * alloc * sizeof ( double );
298  const unsigned int swapsize = 10 * memsize;
299 
300  managedDummySwap swap ( swapsize );
301  cyclicManagedMemory managedMemory ( &swap, memsize );
302 
303  managedPtr<nurfuerspassclass> havefun ( 5, 5 );
304  adhereTo<nurfuerspassclass> hf ( havefun );
305  nurfuerspassclass *hfbuf = hf;
306  for ( int n = 0; n < 5; n++ ) {
307  ASSERT_EQ ( 5, hfbuf[n].val );
308  }
309 
310 }
311 
312 
316 TEST ( managedPtr, Unit_PointerAllocation )
317 {
318  managedDummySwap swap ( 200 );
319  cyclicManagedMemory managedMemory ( &swap, 200 );
320 
321  class A
322  {
323  public:
324  A ( int a = 42 ) : a ( a ) {}
325  int a;
326  };
327 
328  managedPtr<A> myA1;
329  ADHERETOLOC ( A, myA1, A1 );
330  EXPECT_EQ ( 42, A1->a );
331 
332  managedPtr<A> myA2 ( 1 );
333  ADHERETOLOC ( A, myA2, A2 );
334  EXPECT_EQ ( 42, A2->a );
335 
336  managedPtr<A> myA3 ( 1, 43 );
337  ADHERETOLOC ( A, myA3, A3 );
338  EXPECT_EQ ( 43, A3->a );
339 
340  managedPtr<A> myA4 ( 2, 43 );
341  ADHERETOLOC ( A, myA4, A4 );
342  EXPECT_EQ ( 43, A4[0].a );
343  EXPECT_EQ ( 43, A4[1].a );
344 
345 }
346 
347 
351 TEST ( managedPtr, Unit_ZeroSizedObjects )
352 {
353  managedDummySwap swap ( 200 );
354  cyclicManagedMemory managedMemory ( &swap, 200 );
355  managedPtr<bool> ptrnull ( 0 );
356  managedPtr<double> ptr ( 5 );
357  for ( int n = 0; n < 5; n++ ) {
358  ptr[n] = n;
359  }
360 
361  for ( int n = 0; n < 5; n++ ) {
362  EXPECT_EQ ( n, ptr[n] );
363  }
364 }
365 
366 
370 TEST ( managedPtr, Integration_DirectVsSmartAccess )
371 {
372  const unsigned int alloc = 20000u;
373  const unsigned int memsize = 1.5 * alloc * sizeof ( double );
374  const unsigned int swapsize = 10 * memsize;
375  const unsigned int runs = 10;
376  tester test;
377  test.startNewTimeCycle();
378 
379  managedDummySwap swap ( swapsize );
380  cyclicManagedMemory managedMemory ( &swap, memsize );
381 
382  managedPtr<double> ptr1 ( alloc );
383  {
384  ADHERETOLOC ( double, ptr1, lptr1 );
385  for ( unsigned int n = 0; n < alloc; n++ ) {
386  lptr1[n] = n;
387  }
388  }
389  managedPtr<double> ptr2 ( alloc );
390  {
391  ADHERETOLOC ( double, ptr2, lptr2 );
392  for ( unsigned int n = 0; n < alloc; n++ ) {
393  lptr2[n] = -n;
394  }
395  }
396 
397  test.addTimeMeasurement();
398 
399  {
400  ADHERETOLOC ( double, ptr1, lptr1 );
401  for ( unsigned int r = 0; r < runs; ++r ) {
402  for ( unsigned int n = 0; n < alloc; n++ ) {
403  EXPECT_EQ ( n, lptr1[n] );
404  }
405  }
406  }
407  {
408  ADHERETOLOC ( double, ptr2, lptr2 );
409  for ( unsigned int r = 0; r < runs; ++r ) {
410  for ( unsigned int n = 0; n < alloc; n++ ) {
411  EXPECT_EQ ( -n, lptr2[n] );
412  }
413  }
414  }
415 
416  test.addTimeMeasurement();
417 
418  for ( unsigned int r = 0; r < runs; ++r ) {
419  for ( unsigned int n = 0; n < alloc; n++ ) {
420  EXPECT_EQ ( n, ptr1[n] );
421  EXPECT_EQ ( -n, ptr2[n] );
422  }
423  }
424 
425  test.addTimeMeasurement();
426 
427  std::vector<int64_t> durations = test.getDurationsForCurrentCycle();
428  infomsgf ( "Smart access ran for %ld ms", durations[0] );
429  infomsgf ( "Direct access ran for %ld ms", durations[1] );
430  infomsgf ( "Direct access cost %g as much time as smart access", 1.0 * durations[1] / durations[0] );
431 }
432 
433 
434 #ifndef OpenMP_NOT_FOUND
435 
439 TEST ( managedPtr, Unit_MultithreadingConcurrentCreateDelete )
440 {
441  managedDummySwap swap ( 2000 );
442  cyclicManagedMemory managedMemory ( &swap, 2000 );
443 
444  const unsigned int arrsize = 200;
445  managedPtr<double> *arr[arrsize];
446  for ( unsigned int i = 0; i < arrsize; ++i ) {
447  arr[i] = NULL;
448  }
449  #pragma omp parallel for
450  for ( unsigned int i = 0; i < arrsize; ++i ) {
451  arr[i] = new managedPtr<double> ( 1 );
452 
453  }
454  #pragma omp parallel for
455  for ( unsigned int i = 0; i < arrsize; ++i ) {
456  delete arr[i];
457 
458  }
459 
460 }
461 
462 
467 TEST ( managedPtr, Unit_ConcurrentUseAccess )
468 {
469  managedDummySwap swap ( 800 );
470  cyclicManagedMemory managedMemory ( &swap, 400 );
471 
472  managedMemory.setOutOfSwapIsFatal ( false ); //This may be needed by OMP programs
473 
474  managedPtr<double> a ( 40 );
475  managedPtr<double> b ( 40 );
476 
477  #pragma omp parallel for
478  for ( int i = 0; i < 1000; ++i ) {
479  if ( i % 2 == 0 ) {
480  ADHERETOLOC ( double, a, loc );
481  loc[i % 40] = i % 40;
482 
483  } else {
484  ADHERETOLOC ( double, b, loc );
485  loc[i % 40] = i % 40;
486  }
487  }
488 
489  for ( int i = 0; i < 40; ++i ) {
490  if ( i % 2 == 0 ) {
491  ADHERETOLOC ( double, a, loc );
492  ASSERT_EQ ( i % 40, loc[i % 40] );
493 
494  } else {
495  ADHERETOLOC ( double, b, loc );
496  ASSERT_EQ ( i % 40, loc[i % 40] );
497  }
498  }
499 }
500 
501 
506 TEST ( managedPtr, Unit_ConcurrentUseAccessThree )
507 {
508  managedDummySwap swap ( 1200 );
509  cyclicManagedMemory managedMemory ( &swap, 400 );
510  managedMemory.setOutOfSwapIsFatal ( false );
512 
513 
514  #pragma omp parallel for
515  for ( int i = 0; i < 10000; ++i ) {
516  if ( i % 500 == 0 ) { //Don't do this all the time as parallelism is blocked by this and this is what we want to test...
517  EXPECT_TRUE ( managedMemory.checkCycle() );
518  }
519  int idx = i % 3;
520  adhereTo<double> A ( a[idx] );
521  double *loc = A;
522  loc[0] = i;
523  }
524 }
525 #endif
526 
527 
532 {
533 public:
535  ++num_instances; // Also do something in local memory to provoke SEGV if not correctly inited
536  arr[9] = 9;
537  }
538 
540  --num_instances; // Also do something in local memory to provoke SEGV if not correctly loaded
541  arr[9] = 0;
542  }
543 
544  static int num_instances;
545 private:
546  double arr[10];
547 
548 };
550 
551 
555 TEST ( managedPtr, Unit_CallDestructorIfSwapped )
556 {
557  managedDummySwap swap ( sizeof ( destructorTracker ) * 2 );
558  cyclicManagedMemory managedMemory ( & swap, sizeof ( destructorTracker ) * 1.5 ) ;
559 
561  ASSERT_EQ ( 1, destructorTracker::num_instances );
562 
563  //Swap out first one:
565  ASSERT_EQ ( 2, destructorTracker::num_instances );
566 
567  delete ptr2;
568  ASSERT_EQ ( 1, destructorTracker::num_instances );
569 
570  delete ptr1;
571  ASSERT_EQ ( 0, destructorTracker::num_instances );
572 }
573 
574 
578 TEST ( managedPtr, Unit_EmptySizeAllowed )
579 {
580  managedDummySwap swap ( sizeof ( double ) * 2 );
581  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 2 ) ;
582 
583  ASSERT_NO_FATAL_FAILURE (
584  managedPtr<double> ptr ( 0 );
585  adhereTo<double> glue ( ptr );
586  double *mptr = glue;
587  EXPECT_TRUE ( NULL == mptr );
588  );
589 
590 }
591 
592 
596 TEST ( managedPtr, Unit_GetSize )
597 {
598  managedDummySwap swap ( 200 );
599  dummyManagedMemory managedMemory ();
600 
601  managedPtr<double> ptr ( 14 );
602 
603  ASSERT_EQ ( 14, ptr.size() );
604 }
605 
612 TEST ( managedPtr, Unit_ZeroSizedObjectsCanBeOverwrittenSavely )
613 {
614  class destructable
615  {
616  public:
617  destructable() {}
618  ~destructable() {
619  * ( ( char * ) NULL ) = 0x00; //Would segfault if called.
620  }
621  };
622 
623  {
624  // Check that destructor is not called on destruction:
625  managedPtr<destructable> donotkillme ( 0 );
626  }
627  managedPtr<destructable> donotkillme ( 0 );
628  //Check that destructor is also not called for copying:
629  donotkillme = managedPtr<destructable> ( 0 );
630 }
631 
635 TEST ( managedPtr, Unit_OverwriteWhileUsing )
636 {
637  managedDummySwap swap ( sizeof ( double ) * 3 );
638  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 2 ) ;
639 
640  managedPtr<double> ptr1 ( 1 );
641  adhereTo<double> glue ( ptr1 );
642  double *loc = glue;
643 
644  managedPtr<double> ptr2 ( 1 );
645  managedPtr<double> ptr3 ( 1 );
646  //Will not throw as ptr2 is not used and we may destruct:
647  ASSERT_NO_THROW (
648  ptr2 = ptr3;
649  );
650  adhereTo <double>glue2 ( ptr3 );
651  double *data = glue2;
652 
653  //Using source will not give any problems:
654  ASSERT_NO_THROW (
655  ptr2 = ptr3;
656  );
657 
658  //Throws as this would invalidate active pointer:
659  ASSERT_THROW (
660  ptr1 = ptr2, memoryException
661  );
662 }
663 
667 TEST ( managedPtr, Unit_ShallowCopy )
668 {
669  managedDummySwap swap ( sizeof ( double ) * 100 );
670  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 10 ) ;
671 
672  managedPtr<double> ptr1 ( 5 );
673  {
674  ADHERETOLOC ( double, ptr1, loc );
675  for ( int i = 0; i < 5; ++i ) {
676  loc[i] = i;
677  }
678  }
679 
680  managedPtr<double> ptr2 ( ptr1 );
681  {
682  ADHERETOLOC ( double, ptr2, loc );
683  for ( int i = 0; i < 5; ++i ) {
684  ASSERT_EQ ( i, loc[i] );
685  loc[i] = i * 10;
686  }
687  }
688 
689  {
690  ADHERETOLOCCONST ( double, ptr1, loc );
691  for ( int i = 0; i < 5; ++i ) {
692  ASSERT_EQ ( i * 10, loc[i] );
693  }
694  }
695 
696  managedPtr<double> ptr3 = ptr1;
697  {
698  ADHERETOLOC ( double, ptr3, loc );
699  for ( int i = 0; i < 5; ++i ) {
700  ASSERT_EQ ( i * 10, loc[i] );
701  loc[i] = i * 100;
702  }
703  }
704 
705  {
706  ADHERETOLOCCONST ( double, ptr1, loc );
707  for ( int i = 0; i < 5; ++i ) {
708  ASSERT_EQ ( i * 100, loc[i] );
709  }
710  }
711 }
712 
716 TEST ( managedPtr, Unit_TestReassignment )
717 {
718  managedDummySwap swap ( sizeof ( double ) * 100 );
719  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 10 ) ;
720 
721  managedPtr<double> ptr1 ( 5 );
722  {
723  ADHERETOLOC ( double, ptr1, loc );
724  for ( int i = 0; i < 5; ++i ) {
725  loc[i] = i;
726  }
727  }
728 
729  managedPtr<double> ptr2 ( ptr1 );
730  {
731  ADHERETOLOC ( double, ptr2, loc );
732  for ( int i = 0; i < 5; ++i ) {
733  ASSERT_EQ ( i, loc[i] );
734  loc[i] = i * 10;
735  }
736  }
737 
738  {
739  ADHERETOLOCCONST ( double, ptr1, loc );
740  for ( int i = 0; i < 5; ++i ) {
741  ASSERT_EQ ( i * 10, loc[i] );
742  }
743  }
744 
745  ptr1 = ptr2;
746  {
747  ADHERETOLOC ( double, ptr1, loc );
748  for ( int i = 0; i < 5; ++i ) {
749  ASSERT_EQ ( i * 10, loc[i] );
750  loc[i] = i * 100;
751  }
752  }
753 
754  {
755  ADHERETOLOCCONST ( double, ptr2, loc );
756  for ( int i = 0; i < 5; ++i ) {
757  ASSERT_EQ ( i * 100, loc[i] );
758  }
759  }
760 }
761 
765 TEST ( managedPtr, Unit_MultipleAdhereTo )
766 {
767  managedDummySwap swap ( sizeof ( double ) * 100 );
768  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 10 ) ;
769 
770  managedPtr<double> ptr1 ( 5 );
771  {
772  ADHERETOLOC ( double, ptr1, loc );
773  for ( int i = 0; i < 5; ++i ) {
774  loc[i] = i;
775  }
776  }
777 
778  managedPtr<double> ptr2 ( ptr1 );
779  managedPtr<double> &ptr3 = ptr2;
780  {
781  ADHERETOLOC ( double, ptr1, loc1 );
782  ADHERETOLOC ( double, ptr2, loc2 );
783  ADHERETOLOC ( double, ptr3, loc3 );
784 
785  ASSERT_EQ ( loc1, loc2 );
786  ASSERT_EQ ( loc1, loc3 );
787  }
788 }
789 
793 TEST ( managedPtr, Unit_TwoDimensionalPtr )
794 {
795  managedDummySwap swap ( sizeof ( double ) * 1000 );
796  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 15 ) ;
797 
798  managedPtr<double, 2> ptr1 ( 3, 5 );
799 
800  ASSERT_NO_FATAL_FAILURE (
801  for ( int i = 0; i < 3; ++i ) {
802  adhereTo <double> glue ( ptr1[i] );
803  double *loc = glue;
804  for ( int j = 0; j < 5; ++j ) {
805  loc[j] = i * 5 + j;
806  }
807  }
808  );
809 
810  ASSERT_NO_FATAL_FAILURE (
811  for ( int i = 0; i < 3; ++i ) {
812  const adhereTo <double> glue ( ptr1[i] );
813  const double *loc = glue;
814  for ( int j = 0; j < 5; ++j ) {
815  ASSERT_EQ ( i * 5 + j, loc[j] );
816  }
817  }
818  );
819 
820  managedPtr<double> ptr2 ( 15 );
821 
822  ASSERT_NO_FATAL_FAILURE (
823  adhereTo <double> glue ( ptr2 );
824  double *loc = glue;
825  for ( int i = 0; i < 15; ++i ) {
826  loc[i] = i;
827  }
828  );
829 
830  ASSERT_NO_FATAL_FAILURE (
831  for ( int i = 0; i < 3; ++i ) {
832  const adhereTo <double> glue ( ptr1[i] );
833  const double *loc = glue;
834  for ( int j = 0; j < 5; ++j ) {
835  ASSERT_EQ ( i * 5 + j, loc[j] );
836  }
837  }
838  );
839 
840  managedPtr<double, 2> ptr3 ( ptr1 );
841 
842  ASSERT_NO_FATAL_FAILURE (
843  for ( int i = 0; i < 3; ++i ) {
844  adhereTo <double> glue ( ptr3[i] );
845  double *loc = glue;
846  for ( int j = 0; j < 5; ++j ) {
847  ASSERT_EQ ( i * 5 + j, loc[j] );
848  loc[j] += 15;
849  }
850  }
851  );
852 
853  ASSERT_NO_FATAL_FAILURE (
854  for ( int i = 0; i < 3; ++i ) {
855  const adhereTo <double> glue ( ptr1[i] );
856  const double *loc = glue;
857  for ( int j = 0; j < 5; ++j ) {
858  ASSERT_EQ ( i * 5 + j + 15, loc[j] );
859  }
860  }
861  );
862 
863  ptr1 = ptr3;
864 
865  ASSERT_NO_FATAL_FAILURE (
866  for ( int i = 0; i < 3; ++i ) {
867  const adhereTo <double> glue ( ptr1[i] );
868  const double *loc = glue;
869  for ( int j = 0; j < 5; ++j ) {
870  ASSERT_EQ ( i * 5 + j + 15, loc[j] );
871  }
872  }
873  );
874 
875  managedPtr<double, 2> ptr4 = ptr1;
876 
877  ASSERT_NO_FATAL_FAILURE (
878  for ( int i = 0; i < 3; ++i ) {
879  adhereTo <double> glue ( ptr4[i] );
880  double *loc = glue;
881  for ( int j = 0; j < 5; ++j ) {
882  ASSERT_EQ ( i * 5 + j + 15, loc[j] );
883  loc[j] += 15;
884  }
885  }
886  );
887 
888  ASSERT_NO_FATAL_FAILURE (
889  for ( int i = 0; i < 3; ++i ) {
890  const adhereTo <double> glue ( ptr1[i] );
891  const double *loc = glue;
892  for ( int j = 0; j < 5; ++j ) {
893  ASSERT_EQ ( i * 5 + j + 30, loc[j] );
894  }
895  }
896  );
897 
898  managedPtr<double, 2> *ptr5 = new managedPtr<double, 2> ( ptr1 );
899  delete ptr5;
900 
901  ASSERT_NO_FATAL_FAILURE (
902  for ( int i = 0; i < 3; ++i ) {
903  const adhereTo <double> glue ( ptr1[i] );
904  const double *loc = glue;
905  for ( int j = 0; j < 5; ++j ) {
906  ASSERT_EQ ( i * 5 + j + 30, loc[j] );
907  }
908  }
909  );
910 }
911 
915 TEST ( managedPtr, Unit_ThreeDimensionalPtr )
916 {
917  managedDummySwap swap ( sizeof ( double ) * 1000 );
918  cyclicManagedMemory managedMemory ( & swap, sizeof ( double ) * 15 ) ;
919 
920  managedPtr<double, 3> ptr1 ( 3, 5, 4 );
921 
922  ASSERT_NO_FATAL_FAILURE (
923  for ( int i = 0; i < 3; ++i ) {
924  for ( int j = 0; j < 5; ++j ) {
925  adhereTo <double> glue ( ptr1[i][j] );
926  double *loc = glue;
927  for ( int k = 0; k < 4; ++k ) {
928  loc[k] = i * 5 * 4 + j * 4 + k;
929  }
930  }
931  } );
932 
933  managedPtr<double, 3> ptr2 ( ptr1 );
934  managedPtr<double, 3> ptr3 = ptr1;
935 
936  ASSERT_NO_FATAL_FAILURE (
937  for ( int i = 0; i < 3; ++i ) {
938  for ( int j = 0; j < 5; ++j ) {
939  adhereTo <double> glue2 ( ptr2[i][j] );
940  double *loc2 = glue2;
941  adhereTo <double> glue3 ( ptr3[i][j] );
942  double *loc3 = glue3;
943 
944  for ( int k = 0; k < 4; ++k ) {
945  ASSERT_EQ ( i * 5 * 4 + j * 4 + k, loc2[k] );
946  ASSERT_EQ ( i * 5 * 4 + j * 4 + k, loc3[k] );
947  }
948  }
949  } );
950 }
951 
953 
Exception for errors with the memory.
Definition: exceptions.h:87
bool setOutOfSwapIsFatal(bool fatal=true)
set policy what to do when out of memory in both ram and swap
void addTimeMeasurement()
Saves the current timestamp.
Definition: tester.cpp:36
static int num_instances
Main class to fetch memory that is managed by rambrain for actual usage.
Definition: managedPtr.h:48
global_bytesize getUsedMemory() const
returns current ram usage
uint64_t memoryID
void startNewTimeCycle()
Starts a new cycle of time measurements.
Definition: tester.cpp:89
Main class to allocate memory that is managed by the rambrain memory defaultManager.
Definition: managedMemory.h:54
bool checkCycle()
checks whether the scheduler believes to be sane and prints an error message if not ...
static managedMemory * defaultManager
static memoryID parent
std::vector< int64_t > getDurationsForCurrentCycle() const
Take the current cycle of time measurements and calculate all durations in betwen.
Definition: tester.cpp:186
Helper class to track construction and destruction.
RESTORE_WARNINGS
A basic class to be used by tests. Provides helper methods and functionality e.g. time measurements...
Definition: tester.h:32
TEST(managedPtr, Unit_NoMemoryManager)
IGNORE_TEST_WARNINGS
bool setPreemptiveUnloading(bool preemptive)
sets whether scheduler should swap out elements without strict need
a dummy managed Memory that basically does nothing and throws on everything.
scheduler working with a double linked cycle. Details see paper.
A dummy swap that just copies swapped out chunks to a different location in ram.
Backend class to handle raw memory and interaction/storage with managedSwap.
Definition: managedMemory.h:68