11. MVFF (Manual Variable First Fit)

MVFF manually manages variable-sized, unformatted objects. It uses the first fit allocation policy for blocks allocated via mps_alloc().

Johnstone (1997) found that in his test cases:

No version of best fit had more than 5% actual fragmentation. This is also true for all versions of first fit that used an address-ordered free list, and the two versions of first fit that used a FIFO free list. This strongly suggests that the basic best-fit algorithm and the first-fit algorithm with an address-ordered free list are very robust algorithms.

The MVFF pool class also supports buffered allocation (that is, allocation via allocation points), and in this case, the allocation policy is different: the buffers are filled according to the worst fit policy, and allocation always proceeds upwards from the base.

Buffered and unbuffered allocation can be used at the same time, but the first allocation point must be created before any call to mps_alloc().

It is usually not advisable to use buffered and unbuffered allocation on the same pool, because the worst-fit policy of buffer filling will grab all the large blocks, leading to severe fragmentation. If you need both forms of allocation, use two separate pools.

Note that buffered allocation can’t allocate across segment boundaries (see Allocation point implementation for the technical reason). This can cause added external fragmentation if objects are allocated that are a significant fraction of the segment size.

Note

If you need to allocate large objects in an MVFF pool, contact us.

11.1. MVFF properties

11.2. MVFF interface

#include "mpscmvff.h"
mps_class_t mps_class_mvff(void)

Return the pool class for an MVFF (Manual Variable First Fit) pool.

When creating an MVFF pool, mps_pool_create_k() requires six keyword arguments:

  • MPS_KEY_EXTEND_BY (type size_t) is the size of segment that the pool will request from the arena.
  • MPS_KEY_MEAN_SIZE (type size_t) is the predicted mean size of blocks that will be allocated from the pool. This is a hint to the MPS: the pool will be less efficient if this is wrong, but nothing will break.
  • MPS_KEY_ALIGN (type mps_align_t) is the alignment of addresses for allocation (and freeing) in the pool. If an unaligned size is passed to mps_alloc() or mps_free(), it will be rounded up to the pool’s alignment. The minimum alignment supported by pools of this class is sizeof(void *).
  • MPS_KEY_MVFF_ARENA_HIGH (type mps_bool_t) indicates whether new segments for buffered allocation are acquired at high addresses (if true), or at low addresses (if false).
  • MPS_KEY_MVFF_SLOT_HIGH (type mps_bool_t) is undocumented. It must have the same value as MPS_KEY_MVFF_ARENA_HIGH.
  • MPS_KEY_MVFF_FIRST_FIT (type mps_bool_t) is undocumented and must be set to true.

For example:

MPS_ARGS_BEGIN(args) {
    MPS_ARGS_ADD(ARGS, MPS_KEY_EXTEND_BY, 1024 * 1024);
    MPS_ARGS_ADD(ARGS, MPS_KEY_MEAN_SIZE, 32);
    MPS_ARGS_ADD(ARGS, MPS_KEY_ALIGN, 8);
    MPS_ARGS_ADD(ARGS, MPS_KEY_MVFF_ARENA_HIGH, 0);
    MPS_ARGS_ADD(ARGS, MPS_KEY_MVFF_SLOT_HIGH, 0);
    MPS_ARGS_ADD(ARGS, MPS_KEY_MVFF_FIRST_FIT, 1);
    MPS_ARGS_DONE(args);
    res = mps_pool_create_k(&pool, arena, mps_class_mvff(), args);
} MPS_ARGS_END(args);

Deprecated

starting with version 1.112.

When using mps_pool_create(), pass the arguments like this:

mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
                          mps_class_t mps_class_mvff(),
                          mps_size_t extend_size,
                          mps_size_t average_size,
                          mps_align_t alignment,
                          mps_bool_t slot_high,
                          mps_bool_t arena_high,
                          mps_bool_t first_fit)
mps_class_t mps_class_mvff_debug(void)

A debugging version of the MVFF pool class.

When creating a debugging MVFF pool, mps_pool_create_k() requires seven keyword arguments.

  • MPS_KEY_EXTEND_BY, MPS_KEY_MEAN_SIZE, MPS_KEY_ALIGN, MPS_KEY_MVFF_ARENA_HIGH, MPS_KEY_MVFF_SLOT_HIGH, and MPS_KEY_MVFF_FIRST_FIT are as described above, and MPS_KEY_POOL_DEBUG_OPTIONS specifies the debugging :c:options. See mps_debug_option_s.

Deprecated

starting with version 1.112.

When using mps_pool_create(), pass the debugging options, and other arguments like this:

mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
                          mps_class_t mps_class_mvff_debug(),
                          mps_debug_option_s debug_option,
                          mps_size_t extend_size,
                          mps_size_t average_size,
                          mps_align_t alignment,
                          mps_bool_t slot_high,
                          mps_bool_t arena_high,
                          mps_bool_t first_fit)

11.3. MVFF introspection

#include "mpscmvff.h"
size_t mps_mvff_free_size(mps_pool_t pool)

Return the total amount of free space in an MVFF pool.

pool is the MVFF pool.

Returns the total free space in the pool, in bytes(1).

size_t mps_mvff_size(mps_pool_t pool)

Return the total size of an MVFF pool.

pool is the MVFF pool.

Returns the total size of the pool, in bytes(1). This is the sum of allocated space and free space.