SGI second configuration for __default_alloc_template core memory allocation fun

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

  In fact, the topic some curry favour by claptrap, mainly want to express is the existence question of two local chunk_alloc function, want to ask you how to understand the two.

The following gives the chunk_alloc code, and may explain the function and every function of the code.

Memory configuration for SGI is divided into two layers: the first layer directly call malloc, the second layer is a do it yourself a memory pool allocation. The first two layer configuration thought:

Second layer configuration is firstly set up a free_list[16] array, array is a pointer, pointing to a block of memory, a pointer type is defined as follows:

union obj {

  union obj *free_list_link;

  char client_data[1];

};

In conclusion, free_list each subscript link memory size: 8B, 16B, 24B, 32B, 40B,..., 128B. A total of 16.

Now if you want to assign a 32B memory, but the pointer pointed to by free_list[3] NULL, namely, free chain free_list no 32B of memory, it requires the following _S_chunk_alloc to allocate memory for free_list. The default time allocation is 20 the size of 32B memory.

_S_chunk_alloc second is a parameter value is 20, but the system may not be able to allocate 20, so using a reference. _S_chunk_malloc is mainly divided into three kinds of situations to deal with:

1,The existing pool of memory capacity to meet your needs: 32B * 20, returned to give you such a large block of memory,

2,The existing pool of memory capacity can not meet so many, that is 20, but can accommodate up to 1, the first to give you free_list item is assigned a 32B.,

3,The existing pool of memory capacity even one can not meet, it can only use malloc allocates the memory from the heap.

  Allocating memory from the heap, first put some fragmentary memory Fu residual current in the memory pool for free_list,

  Then the stack in malloc memory, modify the memory pool of _S_start_free, _S_end_free pointer. (initial address the two pointers point to the memory pool and the end address).

  Then a recursive call to the _S_chunk_malloc function.


My question is: 1, reset the system memory is a problem, as shown in the following code.

      2,Malloc new memory, modify the _S_end_free code is correct.

All the code is as follows, I doubt explained further below, we first look at the code to understand this function, then see my thoughts went wrong, thank you!

template <bool __threads, int __inst>
char*
__default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, 
                                                            int& __nobjs)
{
    char* __result;
    size_t __total_bytes = __size * __nobjs;
    size_t __bytes_left = _S_end_free - _S_start_free; // Memory pool of surplus space

    if (__bytes_left >= __total_bytes) { // Memory pool of surplus space meets the requirements
        __result = _S_start_free;
        _S_start_free += __total_bytes;
        return(__result);
    } else if (__bytes_left >= __size) { // Memory pool of surplus space can not fully meet the demand, but enough to supply a (with) the above block
        __nobjs = (int)(__bytes_left/__size);
        __total_bytes = __size * __nobjs;
        __result = _S_start_free;
        _S_start_free += __total_bytes;
        return(__result);
    } else { // Memory pool remaining space with a block size is not available
        size_t __bytes_to_get = 
	  2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
        // Try to make use of the left-over piece.
		// The memory pool the remaining use some small residual fraction. 
        if (__bytes_left > 0) {
            _Obj* __STL_VOLATILE* __my_free_list =
                        _S_free_list + _S_freelist_index(__bytes_left); // Here, right? If __bytes_left = 15, _S_freelist_index(15) = 1, 
																		// That is the position of 16B, but only 15B? 

            ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
            *__my_free_list = (_Obj*)_S_start_free;
        }
        _S_start_free = (char*)malloc(__bytes_to_get);
        if (0 == _S_start_free) {
            size_t __i;
            _Obj* __STL_VOLATILE* __my_free_list;
	    _Obj* __p;
            // Try to make do with what we have.  That can't
            // hurt.  We do not try smaller requests, since that tends
            // to result in disaster on multi-process machines.
            for (__i = __size;
                 __i <= (size_t) _MAX_BYTES;
                 __i += (size_t) _ALIGN) {
                __my_free_list = _S_free_list + _S_freelist_index(__i);
                __p = *__my_free_list;
                if (0 != __p) {
                    *__my_free_list = __p -> _M_free_list_link;
                    _S_start_free = (char*)__p;
                    _S_end_free = _S_start_free + __i; // OK here every piece of memory size is __i.? 
                    return(_S_chunk_alloc(__size, __nobjs));
                    // Any leftover piece will eventually make it to the
                    // right free list.
                }
            }
	    _S_end_free = 0;	// In case of exception.
            _S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get);
            // This should either throw an
            // exception or remedy the situation.  Thus we assume it
            // succeeded.
        }
        _S_heap_size += __bytes_to_get;
        _S_end_free = _S_start_free + __bytes_to_get;
        return(_S_chunk_alloc(__size, __nobjs));
    }
}

  I explain the problem:

1,If __bytes_left = 15B, then _S_freelist_index (__bytes_left) = 1, that is to say, should make this a 15B into the free_list 16B, this is good.?

2,_S_end_free = _S_start_free + __i;How to determine the corresponding __i free_list this item size is __i, don't have capacity of > __i, but less than __i + 8? This _S_end_free is not wrong you?


Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by April at November 17, 2013 - 3:59 PM