Saturday, July 27, 2013

Variable size memory pool Vs Fixed size memory pool: Creation

① Difference between variable size memory pool and fixed size memory pool

The variable memory pool is defined with structure T_CMPL which has fields ① size of variable length memory pool ② start address of memory pool area ③ attribute flags such as whether the tasks should be granted memory in the order of FIFO or higher priority.
 
In fixed memory pool, the size of memory pool is not directly defined. Instead, T_CMPF structure has fields of  ① the total number of memory blocks required ② size of each memory block size, are defined. ③ attribute flag is same as variable size memory pool.
 
When considering the implementation, the method to keep track free memory blocks differs for both. In this regard, the initialization differs little.

② Implementation specific differences

In variable memory pool, the free memory blocks are connected through linked list kind of structure as shown in the following figure. Immediately after creation of the memory pool, it will be just one single block of memory as shown in the next figure:

Each block of memory is managed with two fields located at the starting of the memory block itself: ① the next pointer ② length of the memory block including these two fields themselves. For the sake of making the internal implementation easier, the total size of these two fields are made as basic unit size of the memory pool. In other words, the size of memory pool is truncated to the multiple of the basic unit size, any allocation will be done in multiple of the basic unit size and the minimum of memory block will be with basic unit size.

For example, when the word length of the CPU is 4 bytes, the basic unit size will be 8 bytes (2 words). When the user passes the size of memory area as 1028, the maximum memory block size available for the user will be: 1016 bytes.



When the memory pool is allocated into blocks, the usable memory size is reduced further which will be discussed in the next post related to allocation.

Ofcourse, the whole system memory itself is being managed as variable memory pool from where the memory for the variable memory pool and fixed memory pool are allocated. It is kind of recursive!

 ③ ITRON implementation of cre_mpl()

ER cre_mpl(ID mplid, T_CMPL *pk_cmpl)
{
        Check context. If called from ISR,
                return E_CTX;
        Sanity check on arguments
        Enter critical section (Interrupt Disable)
        if (start address of memory pool area is NULL) {
                Allocate the memory from Heap with given memory pool area size
        }
        Keep record of the start address of memory pool area
        Keep record of the total size of memory pool area
        /* Initialize the first and top memory pool header defining the free area */
                Align the memory pool size with alignment requirement from CPU & set as size of free area
                Set next pointer of header as NULL
        Internal structure has one queue to order waiting tasks
        If (tasks are queued in FIFO order)
                Initialize queue as follows:
                ┏━━━━━┯━━━━━━┓
                ┃Queue   │Queue     ┃
                ┃[0]     │Tail       ┃
                ┗━━━━━┷━━━━━━┛
        else (tasks are queued as priority based)
                Initialize as follows:
                ┏━━━━━━━━┯━━┯━━━━┯━━━━━━┓
                ┃Priority0      │1   │Max   │Queue    ┃
                ┃            │    │Pri    │Tail       ┃
                ┗━━━━━━━━┷━━┷━━━━┷━━━━━━┛
        Exit critical section (Interrupt Restore)
        return E_OK;
}

④ ITRON implementation of cre_mpf()

ER cre_mpf(ID mpfid, T_CMPF *pk_cmpf)
{
        Check context. If called from ISR,
                return E_CTX;
        Sanity check on arguments
        Align the block size with alignment requirement from CPU
        if size of block is less than size of a pointer, set block size to size of pointer
        Calculate the total size of memory area from number of blocks and block size
        Enter critical section (Interrupt Disable)
        if (start address of memory pool area is NULL) {
                Allocate the memory from Heap with given memory pool area size
        }
        Keep record of the start address of memory pool area
        Keep record of the total size of memory pool area
        Keep record of the total number of memory blocks
        Initialize the memory pool as follows:
                The first word of each block points to the start of next block
 
        Internal structure has one queue to order waiting tasks
        If (tasks are queued in FIFO order)
                Initialize queue as follows:
                ┏━━━━━┯━━━━━━┓
                ┃Queue   │Queue     ┃
                ┃[0]     │Tail       ┃
                ┗━━━━━┷━━━━━━┛
        else (tasks are queued as priority based)
                Initialize as follows:
                ┏━━━━━━━━┯━━┯━━━━┯━━━━━━┓
                ┃Priority0      │1   │Max   │Queue    ┃
                ┃            │    │Pri    │Tail       ┃
                ┗━━━━━━━━┷━━┷━━━━┷━━━━━━┛
        Exit critical section (Interrupt Restore)
        return E_OK;
}

Hope to follow up in next posts under RTOS label.

No comments: