Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-23 09:18:54

0001 // Created on: 2005-03-15
0002 // Created by: Peter KURNEV
0003 // Copyright (c) 2005-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _Standard_MMgrOpt_HeaderFile
0017 #define _Standard_MMgrOpt_HeaderFile
0018 
0019 #include <Standard_MMgrRoot.hxx>
0020 
0021 #include <mutex>
0022 
0023 /**
0024  * @brief Open CASCADE memory manager optimized for speed.
0025  *
0026  * The behaviour is different for memory blocks of different sizes,
0027  * according to specified options provided to constructor:
0028  *
0029  * - Small blocks with size less than or equal to aCellSize are allocated
0030  *   in big pools of memory. The parameter aNbPages specifies size of
0031  *   these pools in pages (operating system-dependent).
0032  *   When freed, small block is not returned to the system but added
0033  *   into free blocks list and reused when block of the same size is
0034  *   requested.
0035  *
0036  * - Medium size blocks with size less than aThreshold are allocated
0037  *   using malloc() or calloc() function but not returned to the system
0038  *   when method Free() is called; instead they are put into free list
0039  *   and reused when block of the same size is requested.
0040  *   Blocks of medium size stored in free lists can be released to the
0041  *   system (by free()) by calling method Purge().
0042  *
0043  * - Large blocks with size greater than or equal to aThreshold are allocated
0044  *   and freed directly: either using malloc()/calloc() and free(), or using
0045  *   memory mapped files (if option aMMap is True)
0046  *
0047  * Thus the optimization of memory allocation/deallocation is reached
0048  * for small and medium size blocks using free lists method;
0049  * note that space allocated for small blocks cannot be (currently) released
0050  * to the system while space for medium size blocks can be released by method Purge().
0051  *
0052  * Note that destructor of that class frees all free lists and memory pools
0053  * allocated for small blocks.
0054  *
0055  * Note that size of memory blocks allocated by this memory manager is always
0056  * rounded up to 16 bytes. In addition, 8 bytes are added at the beginning
0057  * of the memory block to hold auxiliary information (size of the block when
0058  * in use, or pointer to the next free block when in free list).
0059  * This the expense of speed optimization. At the same time, allocating small
0060  * blocks is usually less costly than directly by malloc since allocation is made
0061  * once (when allocating a pool) and overheads induced by malloc are minimized.
0062  */
0063 class Standard_MMgrOpt : public Standard_MMgrRoot
0064 {
0065 public:
0066   //! Constructor. If aClear is True, the allocated emmory will be
0067   //! nullified. For description of other parameters, see description
0068   //! of the class above.
0069   Standard_EXPORT Standard_MMgrOpt(const bool   aClear     = true,
0070                                    const bool   aMMap      = true,
0071                                    const size_t aCellSize  = 200,
0072                                    const int    aNbPages   = 10000,
0073                                    const size_t aThreshold = 40000);
0074 
0075   //! Frees all free lists and pools allocated for small blocks
0076   Standard_EXPORT ~Standard_MMgrOpt() override;
0077 
0078   //! Allocate aSize bytes; see class description above
0079   Standard_EXPORT void* Allocate(const size_t aSize) override;
0080 
0081   //! Reallocate previously allocated aPtr to a new size; new address is returned.
0082   //! In case that aPtr is null, the function behaves exactly as Allocate.
0083   Standard_EXPORT void* Reallocate(void* thePtr, const size_t theSize) override;
0084 
0085   //! Free previously allocated block.
0086   //! Note that block can not all blocks are released to the OS by this
0087   //! method (see class description)
0088   Standard_EXPORT void Free(void* thePtr) override;
0089 
0090   //! Release medium-sized blocks of memory in free lists to the system.
0091   //! Returns number of actually freed blocks
0092   Standard_EXPORT int Purge(bool isDestroyed) override;
0093 
0094   //! Declaration of a type pointer to the callback function that should accept the following
0095   //! arguments:
0096   //! @param theIsAlloc   true if the data is allocated, false if it is freed
0097   //! @param theStorage   address of the allocated/freed block
0098   //! @param theRoundSize the real rounded size of the block
0099   //! @param theSize      the size of the block that was requested by application (this value is
0100   //! correct only if theIsAlloc is true)
0101   typedef void (*TPCallBackFunc)(const bool   theIsAlloc,
0102                                  void* const  theStorage,
0103                                  const size_t theRoundSize,
0104                                  const size_t theSize);
0105 
0106   //! Set the callback function. You may pass 0 there to turn off the callback.
0107   //! The callback function, if set, will be automatically called from within
0108   //! Allocate and Free methods.
0109   Standard_EXPORT static void SetCallBackFunction(TPCallBackFunc pFunc);
0110 
0111 protected:
0112   //! Internal - initialization of buffers
0113   Standard_EXPORT void Initialize();
0114 
0115   //! Internal - allocation of memory using either malloc or memory mapped files.
0116   //! The size of the actually allocated block may be greater than requested one
0117   //! when memory mapping is used, since it is aligned to page size
0118   size_t* AllocMemory(size_t& aSize);
0119 
0120   //! Internal - deallocation of memory taken by AllocMemory
0121   void FreeMemory(void* aPtr, const size_t aSize);
0122 
0123   //! Internal - free memory pools allocated for small size blocks
0124   void FreePools();
0125 
0126 protected:
0127   bool myClear; //!< option to clear allocated memory
0128 
0129   size_t   myFreeListMax; //!< last allocated index in the free blocks list
0130   size_t** myFreeList;    //!< free blocks list
0131 
0132   size_t  myCellSize;  //!< small blocks size
0133   int     myNbPages;   //!< size (pages) for small block memory pools
0134   size_t  myPageSize;  //!< system-dependent memory page size
0135   size_t* myAllocList; //!< list of memory pools for small blocks
0136   size_t* myNextAddr;  //!< next free address in the active memory pool
0137   size_t* myEndBlock;  //!< end of the active memory pool
0138 
0139   // clang-format off
0140   int myMMap;          //!< non-null if using memory mapped files for allocation of large blocks
0141   // clang-format on
0142   size_t myThreshold; //!< large block size
0143 
0144   std::mutex myMutex;      //!< Mutex to protect free lists data
0145   std::mutex myMutexPools; //!< Mutex to protect small block pools data
0146 };
0147 
0148 #endif