soma-io  5.0.5
allocator.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef SOMAIO_ALLOCATOR_ALLOCATOR_H
35 #define SOMAIO_ALLOCATOR_ALLOCATOR_H
36 //--- soma-io ----------------------------------------------------------------
40 //--- cartobase --------------------------------------------------------------
42 #include <cartobase/smart/rcptr.h>
43 //--- system -----------------------------------------------------------------
44 #include <memory>
45 #include <string>
46 //----------------------------------------------------------------------------
47 
48 namespace soma
49 {
50 
51  //==========================================================================
52  // L O W L E V E L A L L O C A T O R
53  //==========================================================================
63  {
64  public:
65  virtual ~LowLevelAllocator();
66 
67  virtual char *allocate( size_t n, size_t elemsize,
68  DataSource* datasource ) const = 0;
69  virtual void deallocate( char *ptr, size_t n, size_t elemsize ) const = 0;
70 
71  virtual bool canDuplicate() const { return true; }
72 
73  protected:
75  };
76 
77 
78  //==========================================================================
79  // M E M O R Y A L L O C A T O R
80  //==========================================================================
83  {
84  public:
85  virtual ~MemoryAllocator();
86 
87  virtual char *allocate( size_t n, size_t elemsize,
88  DataSource* datasource ) const;
89  virtual void deallocate( char *ptr, size_t n, size_t sz ) const;
90 
91  static const MemoryAllocator & singleton();
92 
93  private:
95  MemoryAllocator() : LowLevelAllocator() { _allocptr() = this; }
96 
97  static MemoryAllocator *& _allocptr();
98  };
99 
100 
101  //==========================================================================
102  // N U L L A L L O C A T O R
103  //==========================================================================
109  {
110  public:
111  virtual ~NullAllocator();
112 
113  virtual char *allocate( size_t n, size_t elemsize,
114  DataSource* datasource ) const;
115  virtual void deallocate( char *ptr, size_t n, size_t sz ) const;
116 
117  static const NullAllocator & singleton();
118 
119  private:
121  NullAllocator() : LowLevelAllocator() { _allocptr() = this; }
122 
123  static NullAllocator *& _allocptr();
124  };
125 
126 
127  std::ostream& operator << ( std::ostream& os,
128  const MemoryAllocator& thing );
129 
130  class AllocatorContext;
131 
132  //==========================================================================
133  // A L L O C A T O R S T R A T E G Y
134  //==========================================================================
151  {
152  public:
156  {
171  };
172 
174  {
175  // No memory mapping : loading on ram
177  MEM = Memory,
178  // Memory mapping
180  // Memory mapping of a copy of the input file
182  MAP_COPY = CopyMap,
183  // Memory mapping with reading only
185  MAP_RO = ReadOnlyMap,
186  // Memory mapping with reading and writing
188  MAP_RW = ReadWriteMap,
189  // No allocation needed : data source is a buffer
191  };
192 
205  static MappingMode mappingMode( DataAccess mode,
206  offset_t buflen,
207  const DataSource* datasource,
208  bool isDiskformatOK,
209  float usefactor = 1 );
210 
212  static bool isMMapCompatible( bool ascii, int byteorder,
213  bool scalefactored = false,
214  int border = 0 );
216  //static bool isMMapCompatible( const carto::AttributedObject & hdr );
217 
224  static void memSizes( offset_t & ram,
225  offset_t & freeram,
226  offset_t & swap );
227 
228  static AllocatorContext allocator( MappingMode mode,
230 
231  static const LowLevelAllocator & lowLevelAllocator( MappingMode m );
232  };
233 
234 
235  //==========================================================================
236  // A L L O C A T O R C O N T E X T
237  //==========================================================================
261  {
262  public:
265 
269  bool isDiskformatOK = false,
270  float usefactor = 1 );
272  AllocatorContext( DataAccess mode,
273  carto::rc_ptr<DataSourceInfo> datasourceinfo,
274  float usefactor = 1 );
276  AllocatorContext( DataAccess mode,
277  const std::string & filename,
278  offset_t offset = 0,
279  bool isDiskformatOK = false,
280  float usefactor = 1 );
282  AllocatorContext( DataAccess mode, float usefactor );
284  AllocatorContext( const LowLevelAllocator* alloc );
287  ~AllocatorContext();
288  AllocatorContext & operator = ( const AllocatorContext & );
289 
291  template<typename T> T* allocate( T*& ptr, size_t n ) const;
292  template<typename T> void deallocate( T* ptr, size_t n ) const;
293  bool canDuplicate() const;
294  MappingMode allocatorType() const;
295 
296  DataAccess accessMode() const { return _access; }
297  void setAccessMode( DataAccess mode );
298 
300  void setDataSource( carto::rc_ptr<DataSource> datasource );
301  const carto::rc_ptr<DataSource> dataSource() const { return _datasource; }
302  carto::rc_ptr<DataSource> dataSource() { return _datasource; }
304  void setDataSourceInfo( carto::rc_ptr<DataSourceInfo> dsi );
305  const carto::rc_ptr<DataSourceInfo> dataSourceInfo() const { return _dsi; }
307 
308  bool isAllocated() const { return _allocated; }
309  float useFactor() const;
310  void setUseFactor( float x );
311  bool allowsMemoryMapping() const;
312  void setAllowsMemoryMapping( bool x );
313 
314  private:
315  mutable const LowLevelAllocator *_alloc;
316  mutable carto::rc_ptr<DataSource> _datasource;
317  mutable carto::rc_ptr<DataSourceInfo> _dsi;
318  DataAccess _access;
319  bool _diskcompat;
320  float _usefact;
321  mutable bool _allocated;
322  mutable bool _forced;
323  };
324 
325  //==========================================================================
326  // A L L O C A T O R C O N T E X T : I N L I N E
327  //==========================================================================
328 
329  template<typename T>
330  inline T* AllocatorContext::allocate( T*& ptr, size_t n ) const
331  {
332  if( _allocated )
333  return ptr; // maybe throw an exception ?
334  _allocated = true;
335 
336  if( !_alloc || !_forced ) {
337  _forced = false;
339  = AllocatorStrategy::mappingMode( _access,
340  offset_t( n ) * sizeof( T ),
341  _datasource.get(),
342  _diskcompat,
343  _usefact );
345  }
346 
347  ptr = reinterpret_cast<T*>( _alloc->allocate( n, sizeof( T ), _datasource.get() ) );
348  #ifdef _MSC_VER
349  #warning uninitialized_fill_n not present in Microsoft standard includes
350  #else
351  // Don't initialize in mem'mapped allocators!
352  if( _alloc == &MemoryAllocator::singleton() )
353  std::uninitialized_fill_n( ptr, n, T() );
354  #endif
355  return ptr;
356  }
357 
358 
359  template<typename T>
360  inline void AllocatorContext::deallocate( T* ptr, size_t n ) const
361  {
362  if( !_allocated )
363  return;
364  _allocated = false;
365  if( _alloc == &MemoryAllocator::singleton() )
366  {
367 #if __cplusplus >= 201100
368  T* p = ptr;
369  std::allocator<T> a;
370  for( size_t i=0; i<n; ++i )
371  a.destroy( p++ );
372 #else
373  std::_Destroy( ptr, ptr + n );
374 #endif
375  }
376  _alloc->deallocate( reinterpret_cast<char*>( ptr ), n, sizeof( T ) );
377  }
378 
379 
381  {
382  return _diskcompat;
383  }
384 
385 
387  {
388  _diskcompat = x;
389  }
390 
391 }
392 
393 
394 #endif
DataAccess accessMode() const
Definition: allocator.h:296
Allocation context.
Definition: allocator.h:260
bool isAllocated() const
Definition: allocator.h:308
static const carto::rc_ptr< DataSource > none()
An empty ref-counter that is more convenient than calling a constructor of rc_ptr<DataSource> (useful...
const carto::rc_ptr< DataSource > dataSource() const
Definition: allocator.h:301
This value is used for sub-volumes or fake volumes using data that are already allocated by another s...
Definition: allocator.h:170
static const LowLevelAllocator & lowLevelAllocator(MappingMode m)
virtual bool canDuplicate() const
Definition: allocator.h:71
AllocatorStrategy::DataAccess DataAccess
Definition: allocator.h:263
Normal allocation mode: allocation in main memory.
Definition: allocator.h:82
const carto::rc_ptr< DataSourceInfo > dataSourceInfo() const
Definition: allocator.h:305
void setAllowsMemoryMapping(bool x)
Definition: allocator.h:386
Abstraction layer for various data sources (file, buffer, socket...).
Definition: datasource.h:64
Mode for read-only access.
Definition: allocator.h:164
Definition: allocator.h:48
DataAccess
Data access modes, they describe what you intend to do with data to be read.
Definition: allocator.h:155
carto::rc_ptr< DataSourceInfo > dataSourceInfo()
Definition: allocator.h:306
bool allowsMemoryMapping() const
Definition: allocator.h:380
virtual char * allocate(size_t n, size_t elemsize, DataSource *datasource) const =0
AllocatorStrategy::MappingMode MappingMode
Definition: allocator.h:264
static const MemoryAllocator & singleton()
Abstract base class for actual allocators types.
Definition: allocator.h:62
static MappingMode mappingMode(DataAccess mode, offset_t buflen, const DataSource *datasource, bool isDiskformatOK, float usefactor=1)
Determines optimal allocator for a data file.
std::ostream & operator<<(std::ostream &os, const MemoryAllocator &thing)
unsigned long long offset_t
Offsets are 64 bits if supported.
Definition: datasource.h:51
carto::rc_ptr< DataSource > dataSource()
Definition: allocator.h:302
virtual void deallocate(char *ptr, size_t n, size_t elemsize) const =0
This allocator doesn&#39;t allocate anything.
Definition: allocator.h:108
T * allocate(T *&ptr, size_t n) const
return value is the same as modifiable input param ptr
Definition: allocator.h:330
Mode for internal modification.
Definition: allocator.h:162
void deallocate(T *ptr, size_t n) const
Definition: allocator.h:360
Determination of the allocation type depending of the buffer size to allocate and the disk format of ...
Definition: allocator.h:150
Mode for read/write access, the input file will be modified and needs read/write permissions.
Definition: allocator.h:167