Skip to content
Snippets Groups Projects
Forked from Core Modules / dune-common
6503 commits behind the upstream repository.
poolallocatortest.cc 3.41 KiB
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <dune/common/poolallocator.hh>
#include <dune/common/alignment.hh>
#include <dune/common/fmatrix.hh>

using namespace Dune;

struct UnAligned
{
  char t;
  char s;
  char k;
};



template<std::size_t size, typename T>
int testPool()
{
  int ret=0;

  Pool<T,size> pool;

  int elements = Pool<T,size>::elements;
  //int poolSize        = Pool<T,size>::size;
  //int chunkSize   = Pool<T,size>::chunkSize;
  //int alignedSize = Pool<T,size>::alignedSize;

  unsigned long* oelements = new unsigned long[10*elements];

  typedef typename Pool<T,size>::Chunk Chunk;

  //Fill 10 chunks
  for(int chunk=0; chunk < 10; ++chunk) {
    //std::cout<< std::endl<<"Chunk "<<chunk<<" ";
    unsigned long element = reinterpret_cast<unsigned long>(pool.allocate());
    void* celement = reinterpret_cast<void*>(element);
    //std::cout << element<<" "<< celement<<",  "<<std::endl;

    Chunk* currentChunk = pool.chunks_;

    assert(element==reinterpret_cast<unsigned long>(currentChunk->memory_));
    unsigned long end = reinterpret_cast<unsigned long>(currentChunk->chunk_)+Pool<T,size>::chunkSize;

    if(element< reinterpret_cast<unsigned long>(currentChunk->chunk_))
    {
      std::cerr <<" buffer overflow during first alloc: "<<reinterpret_cast<unsigned long>(currentChunk->chunk_)
                <<">"<<element<<"+"<<sizeof(T)<<std::endl;
      return ++ret;
    }

    if(end < element + sizeof(T)) {
      std::cerr <<" buffer overflow during first alloc: "<<end<<"<"<<element<<"+"<<sizeof(T)<<std::endl;
      return ++ret;
    }

    oelements[chunk*elements]=element;

    for(int i=1; i < elements; i++)
    {
      element = reinterpret_cast<unsigned long>(pool.allocate());
      celement = reinterpret_cast<void*>(element);

      //  std::cout << element<<" "<<celement<<",  "<<std::endl;
      if(element< reinterpret_cast<unsigned long>(currentChunk->chunk_)) {
        std::cerr <<" buffer underflow during first alloc: "<<reinterpret_cast<unsigned long>(currentChunk->chunk_)
                  <<">"<<element<<"+"<<sizeof(T)<<std::endl;
        return ++ret;
      }

      if(end < element + sizeof(T)) {
        std::cerr <<" buffer overflow during "<<i<<" alloc: "<<end<<"<"<<element+sizeof(T)<<std::endl;
        return ++ret;

      }

      if(oelements[chunk*elements+i-1]+sizeof(T)>element) {
        std::cerr<<"allocated elements overlap!"<<std::endl;
        return ++ret;
      }

      oelements[chunk*elements+i]=element;
    }
  }



  for(int i=0; i < elements*10; ++i)
    pool.free(reinterpret_cast<T*>(oelements+i));
  delete[] oelements;

  return ret;
}

template<typename T>
int testPool()
{
  const std::size_t size = sizeof(T)>=2 ? sizeof(T)-2 : 0;

  int ret=0;

  std::cout<<"Checking "<<typeid(T).name()<<" sizeof="<<sizeof(T)<<" with size "<< size<<
  " alignment="<<AlignmentOf<T>::value<<std::endl;

  //ret += testPool<0,T>();
  //ret += testPool<size,T>();
  ret += testPool<5*size,T>();
  ret += testPool<11*size,T>();
  ret += testPool<33*size,T>();

  return ret;
}
int main(int argc, char **argv)
{
  int ret=0;

  ret += testPool<int>();

  ret+= testPool<double>();

  ret+= testPool<char>();

  ret += testPool<Dune::FieldMatrix<double,10,10> >();


  std::cout<<AlignmentOf<UnAligned>::value<<" "<<sizeof(UnAligned)<<std::endl;

  ret += testPool<UnAligned>();

  return ret;
}