Logo Search packages:      
Sourcecode: sofia-sip version File versions  Download package

Memory Management Tutorial

Detailed Description

su_alloc.c Home-based memory management.

Pekka Pessi <Pekka.Pessi@nokia.com>.
Created: Thu Aug 19 01:12:25 1999 ppessi
This page gives a short overview of home-based memory management used with Sofia. Such home-based memory management is useful when a lot of memory blocks are allocated for given task. The allocations are done via the memory home, which keeps a reference to each block. When the memory home is then freed, it will free all blocks to which it has reference.

Typically, there is a home object which contains a su_home_t structure in the beginning of the object (sort of inheritance from su_home_t):

 struct context {
   su_home_t ctx_home[1];
   other_t  *ctx_stuff;

A new home memory pool can be created with su_home_new():

 struct context *ctx = su_home_new(sizeof (struct context));

It is also possible to create a secondary memory pool that can be released separately:

 struct context *ctx = su_home_clone(tophome, sizeof (struct context));

Note that the tophome has a reference to ctx structure; whenever tophome is freed, the ctx is also freed.

You can also create an independent home object by passing NULL as tophome argument. This is identical to the call to su_home_new().

The memory allocations using ctx proceed then as follows:

    zeroblock = su_zalloc(ctx->ctx_home, sizeof (*zeroblock));

The home memory pool - the home object and all the memory blocks allocated using it - are freed when su_home_unref() is called:


For historical reasons, su_home_unref() is also known as su_home_zap().
As you might have guessed, it is also possible to use reference counting with home objects. The function su_home_ref() increases the reference count, su_home_unref() decreases. A newly allocated home object has reference count of 1.

Please note that while it is possible to create new references to secondary home objects which have a parent home, the secondary home objects will always be destroyed when the parent home is destroyed even if there are other references left to them.
The memory blocks in a cloned home object are freed when the object with home itself is freed:
    su_free(tophome, ctx);

The su_home_destroy() function is deprecated as it does not free the home object itself.

The function su_home_init() initializes a home object with infinite reference count. It must be deinitialized with su_home_deinit().


It is possible to give a destructor function to a home object. The destructor releases other resources associated with the home object besides memory. The destructor function will be called when the reference count of home reaches zero (upon calling su_home_unref()) or the home object is otherwise deinitialized (calling su_home_deinit() on objects allocated from stack).

Combining Allocations

In some cases, an operation that makes multiple memory allocations may fail, making those allocations redundant. If the allocations are made through a temporary home, they can be conveniently freed by calling su_home_deinit(), for instance. If, however, the operation is successful, and one wants to keep the allocations, the allocations can be combined into an existing home with su_home_move(). For example,
 int example(su_home_t *home, ...) 
   su_home_t temphome[1] = { SU_HOME_INIT(temphome) };
   ... do lot of allocations with temphome ...
   if (success) 
     su_home_move(home, temphome);

   return success;

Note that the temphome is deinitialized in every case, but when operation is successful, the allocations are moved from temphome to home.

Threadsafe Operation

If multiple threads need to access same home object, it must be marked as threadsafe by calling su_home_threadsafe() with the home pointer as argument. The threadsafeness is not inherited by clones.

The threadsafe home objects can be locked and unlocked with su_home_mutex_lock() and su_home_mutex_unlock().

Preloading a Memory Home

In some situations there is quite heavy overhead when using the global heap allocator. The overhead caused by the large number of small allocations can be reduced by using su_home_preload(): it allocates or preloads some a memory to home to be used as a kind of private heap. The preloaded memory area is then used to satisfy small enough allocations. For instance, the SIP parser typically preloads some 2K of memory when it starts to parse the message.

Using Stack

In some situation, it is sensible to use memory allocated from stack for some operations. The su_home_auto() function can be used for that purpose. The memory area from stack is used to satisfy the allocations as far as possible; if it is not enough, allocation is made from heap.

The word auto refers to the automatic scope; however, the home object initialized with su_home_auto() must be explicitly deinitialized with su_home_deinit() when the program exits the scope where the stack frame used in su_home_auto() was allocate.


file  su_alloc.h
file  su_alloc_stat.h


#define va_copy(dst, src)   (memcpy(&(dst), &(src), sizeof (va_list)))


int su_home_threadsafe (su_home_t *home)
 Thread-locking for su_alloc module.
char * su_strdup (su_home_t *home, char const *s)

Generated by  Doxygen 1.6.0   Back to index