⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap_allocator.h

📁 linux下编程用 编译软件
💻 H
📖 第 1 页 / 共 3 页
字号:
	    else	      __len = __half;	  }	return __first;      }    template<typename _InputIterator, typename _Predicate>      inline _InputIterator      __find_if(_InputIterator __first, _InputIterator __last, _Predicate __p)      {	while (__first != __last && !__p(*__first))	  ++__first;	return __first;      }    /** @brief The number of Blocks pointed to by the address pair     *  passed to the function.     */    template<typename _AddrPair>      inline size_t      __num_blocks(_AddrPair __ap)      { return (__ap.second - __ap.first) + 1; }    /** @brief The number of Bit-maps pointed to by the address pair     *  passed to the function.     */    template<typename _AddrPair>      inline size_t      __num_bitmaps(_AddrPair __ap)      { return __num_blocks(__ap) / size_t(bits_per_block); }    // _Tp should be a pointer type.    template<typename _Tp>      class _Inclusive_between       : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>      {	typedef _Tp pointer;	pointer _M_ptr_value;	typedef typename std::pair<_Tp, _Tp> _Block_pair;	      public:	_Inclusive_between(pointer __ptr) : _M_ptr_value(__ptr) 	{ }		bool 	operator()(_Block_pair __bp) const throw()	{	  if (std::less_equal<pointer>()(_M_ptr_value, __bp.second) 	      && std::greater_equal<pointer>()(_M_ptr_value, __bp.first))	    return true;	  else	    return false;	}      };      // Used to pass a Functor to functions by reference.    template<typename _Functor>      class _Functor_Ref       : public std::unary_function<typename _Functor::argument_type, 				   typename _Functor::result_type>      {	_Functor& _M_fref;	      public:	typedef typename _Functor::argument_type argument_type;	typedef typename _Functor::result_type result_type;	_Functor_Ref(_Functor& __fref) : _M_fref(__fref) 	{ }	result_type 	operator()(argument_type __arg) 	{ return _M_fref(__arg); }      };    /** @class  _Ffit_finder bitmap_allocator.h bitmap_allocator.h     *     *  @brief  The class which acts as a predicate for applying the     *  first-fit memory allocation policy for the bitmap allocator.     */    // _Tp should be a pointer type, and _Alloc is the Allocator for    // the vector.    template<typename _Tp>      class _Ffit_finder       : public std::unary_function<typename std::pair<_Tp, _Tp>, bool>      {	typedef typename std::pair<_Tp, _Tp> _Block_pair;	typedef typename balloc::__mini_vector<_Block_pair> _BPVector;	typedef typename _BPVector::difference_type _Counter_type;	size_t* _M_pbitmap;	_Counter_type _M_data_offset;      public:	_Ffit_finder() : _M_pbitmap(0), _M_data_offset(0)	{ }	bool 	operator()(_Block_pair __bp) throw()	{	  // Set the _rover to the last physical location bitmap,	  // which is the bitmap which belongs to the first free	  // block. Thus, the bitmaps are in exact reverse order of	  // the actual memory layout. So, we count down the bimaps,	  // which is the same as moving up the memory.	  // If the used count stored at the start of the Bit Map headers	  // is equal to the number of Objects that the current Block can	  // store, then there is definitely no space for another single	  // object, so just return false.	  _Counter_type __diff = 	    __gnu_cxx::balloc::__num_bitmaps(__bp);	  if (*(reinterpret_cast<size_t*>		(__bp.first) - (__diff + 1))	      == __gnu_cxx::balloc::__num_blocks(__bp))	    return false;	  size_t* __rover = reinterpret_cast<size_t*>(__bp.first) - 1;	  for (_Counter_type __i = 0; __i < __diff; ++__i)	    {	      _M_data_offset = __i;	      if (*__rover)		{		  _M_pbitmap = __rover;		  return true;		}	      --__rover;	    }	  return false;	}    	size_t*	_M_get() const throw()	{ return _M_pbitmap; }	_Counter_type	_M_offset() const throw()	{ return _M_data_offset * size_t(bits_per_block); }      };    /** @class  _Bitmap_counter bitmap_allocator.h bitmap_allocator.h     *     *  @brief  The bitmap counter which acts as the bitmap     *  manipulator, and manages the bit-manipulation functions and     *  the searching and identification functions on the bit-map.     */    // _Tp should be a pointer type.    template<typename _Tp>      class _Bitmap_counter      {	typedef typename balloc::__mini_vector<typename std::pair<_Tp, _Tp> > 	_BPVector;	typedef typename _BPVector::size_type _Index_type;	typedef _Tp pointer;    	_BPVector& _M_vbp;	size_t* _M_curr_bmap;	size_t* _M_last_bmap_in_block;	_Index_type _M_curr_index;          public:	// Use the 2nd parameter with care. Make sure that such an	// entry exists in the vector before passing that particular	// index to this ctor.	_Bitmap_counter(_BPVector& Rvbp, long __index = -1) : _M_vbp(Rvbp)	{ this->_M_reset(__index); }    	void 	_M_reset(long __index = -1) throw()	{	  if (__index == -1)	    {	      _M_curr_bmap = 0;	      _M_curr_index = static_cast<_Index_type>(-1);	      return;	    }	  _M_curr_index = __index;	  _M_curr_bmap = reinterpret_cast<size_t*>	    (_M_vbp[_M_curr_index].first) - 1;	  	  _BALLOC_ASSERT(__index <= (long)_M_vbp.size() - 1);		  _M_last_bmap_in_block = _M_curr_bmap	    - ((_M_vbp[_M_curr_index].second 		- _M_vbp[_M_curr_index].first + 1) 	       / size_t(bits_per_block) - 1);	}    	// Dangerous Function! Use with extreme care. Pass to this	// function ONLY those values that are known to be correct,	// otherwise this will mess up big time.	void	_M_set_internal_bitmap(size_t* __new_internal_marker) throw()	{ _M_curr_bmap = __new_internal_marker; }    	bool	_M_finished() const throw()	{ return(_M_curr_bmap == 0); }    	_Bitmap_counter&	operator++() throw()	{	  if (_M_curr_bmap == _M_last_bmap_in_block)	    {	      if (++_M_curr_index == _M_vbp.size())		_M_curr_bmap = 0;	      else		this->_M_reset(_M_curr_index);	    }	  else	    --_M_curr_bmap;	  return *this;	}    	size_t*	_M_get() const throw()	{ return _M_curr_bmap; }    	pointer 	_M_base() const throw()	{ return _M_vbp[_M_curr_index].first; }	_Index_type	_M_offset() const throw()	{	  return size_t(bits_per_block)	    * ((reinterpret_cast<size_t*>(this->_M_base()) 		- _M_curr_bmap) - 1);	}    	_Index_type	_M_where() const throw()	{ return _M_curr_index; }      };    /** @brief  Mark a memory address as allocated by re-setting the     *  corresponding bit in the bit-map.     */    inline void     __bit_allocate(size_t* __pbmap, size_t __pos) throw()    {      size_t __mask = 1 << __pos;      __mask = ~__mask;      *__pbmap &= __mask;    }      /** @brief  Mark a memory address as free by setting the     *  corresponding bit in the bit-map.     */    inline void     __bit_free(size_t* __pbmap, size_t __pos) throw()    {      size_t __mask = 1 << __pos;      *__pbmap |= __mask;    }  } // namespace balloc  /** @brief  Generic Version of the bsf instruction.   */  inline size_t   _Bit_scan_forward(size_t __num)  { return static_cast<size_t>(__builtin_ctzl(__num)); }  /** @class  free_list bitmap_allocator.h bitmap_allocator.h   *   *  @brief  The free list class for managing chunks of memory to be   *  given to and returned by the bitmap_allocator.   */  class free_list  {    typedef size_t* value_type;    typedef balloc::__mini_vector<value_type> vector_type;    typedef vector_type::iterator iterator;    struct _LT_pointer_compare    {      bool      operator()(const size_t* __pui, 		 const size_t __cui) const throw()      { return *__pui < __cui; }    };#if defined __GTHREADS    _Mutex*    _M_get_mutex()    {      static _Mutex _S_mutex;      return &_S_mutex;    }#endif    vector_type&    _M_get_free_list()    {      static vector_type _S_free_list;      return _S_free_list;    }    /** @brief  Performs validation of memory based on their size.     *     *  @param  __addr The pointer to the memory block to be     *  validated.     *     *  @detail  Validates the memory block passed to this function and     *  appropriately performs the action of managing the free list of     *  blocks by adding this block to the free list or deleting this     *  or larger blocks from the free list.     */    void    _M_validate(size_t* __addr) throw()    {      vector_type& __free_list = _M_get_free_list();      const vector_type::size_type __max_size = 64;      if (__free_list.size() >= __max_size)	{	  // Ok, the threshold value has been reached.  We determine	  // which block to remove from the list of free blocks.	  if (*__addr >= *__free_list.back())	    {	      // Ok, the new block is greater than or equal to the	      // last block in the list of free blocks. We just free	      // the new block.	      ::operator delete(static_cast<void*>(__addr));	      return;	    }	  else	    {	      // Deallocate the last block in the list of free lists,	      // and insert the new one in it's correct position.	      ::operator delete(static_cast<void*>(__free_list.back()));	      __free_list.pop_back();	    }	}	        // Just add the block to the list of free lists unconditionally.      iterator __temp = __gnu_cxx::balloc::__lower_bound	(__free_list.begin(), __free_list.end(), 	 *__addr, _LT_pointer_compare());      // We may insert the new free list before _temp;      __free_list.insert(__temp, __addr);    }    /** @brief  Decides whether the wastage of memory is acceptable for     *  the current memory request and returns accordingly.     *     *  @param __block_size The size of the block available in the free     *  list.     *     *  @param __required_size The required size of the memory block.     *     *  @return true if the wastage incurred is acceptable, else returns     *  false.     */    bool     _M_should_i_give(size_t __block_size, 		     size_t __required_size) throw()    {      const size_t __max_wastage_percentage = 36;      if (__block_size >= __required_size && 	  (((__block_size - __required_size) * 100 / __block_size)	   < __max_wastage_percentage))	return true;      else	return false;    }  public:    /** @brief This function returns the block of memory to the     *  internal free list.     *     *  @param  __addr The pointer to the memory block that was given     *  by a call to the _M_get function.     */    inline void     _M_insert(size_t* __addr) throw()    {#if defined __GTHREADS      _Auto_Lock __bfl_lock(_M_get_mutex());#endif      // Call _M_validate to decide what should be done with      // this particular free list.      this->_M_validate(reinterpret_cast<size_t*>(__addr) - 1);      // See discussion as to why this is 1!    }        /** @brief  This function gets a block of memory of the specified     *  size from the free list.     *     *  @param  __sz The size in bytes of the memory required.     *     *  @return  A pointer to the new memory block of size at least     *  equal to that requested.     */    size_t*    _M_get(size_t __sz) throw(std::bad_alloc);    /** @brief  This function just clears the internal Free List, and     *  gives back all the memory to the OS.     */    void     _M_clear();  };  // Forward declare the class.  template<typename _Tp>     class bitmap_allocator;  // Specialize for void:  template<>    class bitmap_allocator<void>    {    public:      typedef void*       pointer;      typedef const void* const_pointer;      // Reference-to-void members are impossible.      typedef void  value_type;      template<typename _Tp1>        struct rebind	{	  typedef bitmap_allocator<_Tp1> other;	};    };  template<typename _Tp>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -