From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libstdc++-v3/doc/html/manual/bitmap_allocator.html | 340 +++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 libstdc++-v3/doc/html/manual/bitmap_allocator.html (limited to 'libstdc++-v3/doc/html/manual/bitmap_allocator.html') diff --git a/libstdc++-v3/doc/html/manual/bitmap_allocator.html b/libstdc++-v3/doc/html/manual/bitmap_allocator.html new file mode 100644 index 000000000..be584e403 --- /dev/null +++ b/libstdc++-v3/doc/html/manual/bitmap_allocator.html @@ -0,0 +1,340 @@ + + +bitmap_allocator

+

+ The Free List Store (referred to as FLS for the remaining part of this + document) is the Global memory pool that is shared by all instances of + the bitmapped allocator instantiated for any type. This maintains a + sorted order of all free memory blocks given back to it by the + bitmapped allocator, and is also responsible for giving memory to the + bitmapped allocator when it asks for more. +

+ Internally, there is a Free List threshold which indicates the + Maximum number of free lists that the FLS can hold internally + (cache). Currently, this value is set at 64. So, if there are + more than 64 free lists coming in, then some of them will be given + back to the OS using operator delete so that at any given time the + Free List's size does not exceed 64 entries. This is done because + a Binary Search is used to locate an entry in a free list when a + request for memory comes along. Thus, the run-time complexity of + the search would go up given an increasing size, for 64 entries + however, lg(64) == 6 comparisons are enough to locate the correct + free list if it exists. +

+ Suppose the free list size has reached it's threshold, then the + largest block from among those in the list and the new block will + be selected and given back to the OS. This is done because it + reduces external fragmentation, and allows the OS to use the + larger blocks later in an orderly fashion, possibly merging them + later. Also, on some systems, large blocks are obtained via calls + to mmap, so giving them back to free system resources becomes most + important. +

+ The function _S_should_i_give decides the policy that determines + whether the current block of memory should be given to the + allocator for the request that it has made. That's because we may + not always have exact fits for the memory size that the allocator + requests. We do this mainly to prevent external fragmentation at + the cost of a little internal fragmentation. Now, the value of + this internal fragmentation has to be decided by this function. I + can see 3 possibilities right now. Please add more as and when you + find better strategies. +

+ Currently, (3) is being used with a value of 36% Maximum wastage per + Super Block. +

+ Each Super Block will be of some size that is a multiple of the + number of Bits Per Block. Typically, this value is chosen as + Bits_Per_Byte x sizeof(size_t). On an x86 system, this gives the + figure 8 x 4 = 32. Thus, each Super Block will be of size 32 + x Some_Value. This Some_Value is sizeof(value_type). For now, let + it be called 'K'. Thus, finally, Super Block size is 32 x K bytes. +

+ This value of 32 has been chosen because each size_t has 32-bits + and Maximum use of these can be made with such a figure. +

+ Consider a block of size 64 ints. In memory, it would look like this: + (assume a 32-bit system where, size_t is a 32-bit entity). +


+ The first Column(268) represents the size of the Block in bytes as + seen by the Bitmap Allocator. Internally, a global free list is + used to keep track of the free blocks used and given back by the + bitmap allocator. It is this Free List Store that is responsible + for writing and managing this information. Actually the number of + bytes allocated in this case would be: 4 + 4 + (4x2) + (64x4) = + 272 bytes, but the first 4 bytes are an addition by the Free List + Store, so the Bitmap Allocator sees only 268 bytes. These first 4 + bytes about which the bitmapped allocator is not aware hold the + value 268. +

+ What do the remaining values represent?

+ The 2nd 4 in the expression is the sizeof(size_t) because the + Bitmapped Allocator maintains a used count for each Super Block, + which is initially set to 0 (as indicated in the diagram). This is + incremented every time a block is removed from this super block + (allocated), and decremented whenever it is given back. So, when + the used count falls to 0, the whole super block will be given + back to the Free List Store. +

+ The value 4294967295 represents the integer corresponding to the bit + representation of all bits set: 11111111111111111111111111111111. +

+ The 3rd 4x2 is size of the bitmap itself, which is the size of 32-bits + x 2, + which is 8-bytes, or 2 x sizeof(size_t). +

+ The allocate function is specialized for single object allocation + ONLY. Thus, ONLY if n == 1, will the bitmap_allocator's + specialized algorithm be used. Otherwise, the request is satisfied + directly by calling operator new. +

+ Suppose n == 1, then the allocator does the following: +

  1. + Checks to see whether a free block exists somewhere in a region + of memory close to the last satisfied request. If so, then that + block is marked as allocated in the bit map and given to the + user. If not, then (2) is executed. +

  2. + Is there a free block anywhere after the current block right + up to the end of the memory that we have? If so, that block is + found, and the same procedure is applied as above, and + returned to the user. If not, then (3) is executed. +

  3. + Is there any block in whatever region of memory that we own + free? This is done by checking +

    + Note: Here we are never touching any of the memory that the + user will be given, and we are confining all memory accesses + to a small region of memory! This helps reduce cache + misses. If this succeeds then we apply the same procedure on + that bit-map as (1), and return that block of memory to the + user. However, if this process fails, then we resort to (4). +

  4. + This process involves Refilling the internal exponentially + growing memory pool. The said effect is achieved by calling + _S_refill_pool which does the following: +

+Thus, you can clearly see that the allocate function is nothing but a +combination of the next-fit and first-fit algorithm optimized ONLY for +single object allocations. +

+ The deallocate function again is specialized for single objects ONLY. + For all n belonging to > 1, the operator delete is called without + further ado, and the deallocate function returns. +

+ However for n == 1, a series of steps are performed: +

+ Now, whenever a block is freed, the use count of that particular + super block goes down by 1. When this use count hits 0, we remove + that super block from the list of all valid super blocks stored in + the vector. While doing this, we also make sure that the basic + invariant is maintained by making sure that _S_last_request and + _S_last_dealloc_index point to valid locations within the vector. +

-- cgit v1.2.3