#include "du.h"
DU_PoolDesc DU_poolCreate(bufSize, nuOfBufs, nuOfViews)
Int bufSize, nuOfBufs, nuOfViews;
DU_View DU_alloc(DU_PoolDesc pool, Int nuOfBytes);
DU_View DU_link(DU_View view);
Void DU_free(DU_View view);
Void DU_prepend(DU_View view, Int nuOfBytes);
Void DU_adjust(DU_View view, Int nuOfBytes);
Void DU_strip(DU_View view, Int nuOfBytes);
Ptr DU_data(DU_View view);
Int DU_size(DU_View view);
Ptr DU_vToUinfo(DU_View view);
DU_View DU_uInfoToV(Ptr uInfo);
DU_ module provides an environment independent interface to a set of facilities providing data unit management capabilities. Propagation of protocol data through the lower layers is accomplished through the DU_ module. Data is not copied as it propagates through Open C Layers. By minimizing memory-to-memory block transfers higher performance is achieved.
When propagating down the layers, initially a data unit is allocated at the top layer. This data unit is stored in a buffer that is large enough to contain all protocol control information that any of the lower layers may prepend to it. (N+1) Open C Layer passes a "view" of the data unit as an (N)-SDU to (N) Open C Layer. (N) Open C Layer appends its (N)-PCI to the view and delivers its (N)-PDU to (N-1) Open C Layer. This is repeated until the data unit is reached to the bottom layer.
When propagating up the layers, initially the bottom layer allocates the data unit. (N-1) Open C Layer delivers a view of the data unit as an (N-1)-SDU to (N) Open C Layer. (N) layer strips its PCI from the (N)-PDU and delivers the resulting (N)-SDU to (N+1) layer. This is repeated until the data unit is reached to the top layer.
The Data Unit management module is a set of facilities and data abstractions that can create, manipulate, and delete data units. DU_ facilities may be implemented based on SF_mem facilities described in the previews sections. Description of DU_ services in this section is based around such an implementation. This concrete example implementation eases the understanding of the DU_ module interface description.
Four basic data structures are central to DU_ module:
typedef struct DU\_Elem *DU\_View;provides a convenient abstraction over this commonly manipulated data structure. One field in struct DU_Elem is a pointer to du_BufInfo . Each DU_Elem contains an area of memory reserved for the user. The size of this user information area is implementation specific. Each DU_Elem is expected to allow for a QU_elem to be casted over it.
An allocated DU_View and a free DU_View are illustrated in the following two figures.
DU_poolCreate is expected to be invoked during initialization of the system. DU_poolCreate creates a data unit pool and returns a pool descriptor. All Open C Layers may rely on the existence of a buffer pool called G_duMainPool. The external declaration of G_duMainPoool is expected to be in g.h. Specified number of du_BufInfo and DU_Views are reserved. Several buffer pools with potentially different buffer sizes may coexists in Open C Environment.
DU_alloc involves the allocation of one du_BufInfo from the specified pool and the allocation of one DU_Elem. DU_Elem is then associated with du_BufInfo. The DU_Elem is a specific view private to the caller. Each DU_Elem is expected to allow for a QU_elem to be casted over it. DU_alloc performs a QU_init to the allocated DU_View . The amount of data specified for allocation, must be smaller than the maximum buffer size associated with the specified pool. The remaining space (maximum buffer size minus the requested buffer size) can be accessed through the DU_prepend facility.
The following figure illustrates the status of DU_ structures after a DU_alloc.
DU_free deallocates the specified DU_View . If no other views of the buffer exists then the du_BufInfo associated with DU_View is also deallocated. du_BufInfo is preserved for as long as there is at least one DU_View referring to it. The number of references to each du_BufInfo is maintained in refCount field. Upon allocation this refCount is set to 1. Each DU_link increments refCount by 1. Each DU_free decrements refCount by 1.
The following figure demonstrates the status of DU_ structures after DU_free invocation.
DU_PoolDesc DU_poolCreate(bufSize, nuOfBufs, nuOfViews)
Int int bufSize, nuOfBufs, nuOfViews;
A buffer pool descriptor (DU_PoolDesc) must be obtained before any views that are associated with it can be allocated. The return value of this function must be used in future usage of DU_ facilities referring to this pool. bufSize specifies the maximum size of the buffers that can be allocated from this pool. nuOfBufs specifies how many du_BufInfos will be available for allocation. nuOfBufs specifies how many DU_Views will be available for allocation or linkage.
Open C Layers can assume the existence of one buffer pool named G_duMainPool. Therefore:
G_duMainPool = DU_poolCreate(bufSize, nuOfBufs, nuOfViews);
is expected of G_ module.
DU_View DU_alloc(DU_PoolDesc pool, int nuOfBytes);
DU_alloc, allocates a new du_BufInfo structure from the specified pool pool. pool must have been obtained through DU_poolCreate . A DU_Elem is allocated and initialized according to the specified nuOfBytes. A reference to DU_Elem is returned to the user as a DU_View. NULL is returned if no du_BufInfo were available or if no DU_View were available or if the nuOfBytes argument was larger than the maximum buffer size associated with pool. du_BufInfo.refCount is set to 1.
DU_View DU_link(DU_View view);
DU_link provides an additional view over an existing du_BufInfo. view must have been obtained through DU_alloc. NULL is returned if there are no DU_Views remaining. du_BufInfo.refCount is incremented.
Void DU_free(DU_View view);
DU_free deallocates view. view must have been obtained through DU_alloc or DU_link. du_BufInfo.refCount is decremented. If refCount becomes zero, the du_BufInfo is no longer in use and du_BufInfo is returned to the buffer pool from which it was originally allocated.
Void DU_prepend(DU_View view, Int nuOfBytes);
Void DU_adjust(DU_View view, Int nuOfBytes);
Void DU_strip(DU_View view, Int nuOfBytes);
Ptr DU_data(DU_View view);
Int DU_size(DU_View view);
DU_prepend facility prepends bytes at the beginning of the specified data unit. It is often used to create space for the Protocol Control Information (PCI) to be prepended by Open C Layers. It is the responsibility of the user to to assure the availability of space. DU_prepend does not do any range checking for excessive prepends. The appended bytes are not initialized to any specific value.
DU_strip facility strips (removes) nuOfBytes bytes from the beginning of the view. It is often used to remove protocol control information from PDUs as they propagate up the layers.
DU_adjust facility adjusts (moves) the end of buffer pointer by nuOfBytes bytes. The effect of DU_adjust is not private to view. All views of DU_Elem.bufInfo are affected.
DU_data facility returns a pointer to the first byte of data as viewed through the specified view. If view is NULL, NULL is returned.
DU_size facility returns the current length of the buffer as observed by the specified view. If view is a NULL pointer, zero is returned.
Ptr DU_vToUinfo(DU_View view);
DU_View DU_uInfoToV(Ptr uInfo);
In order to access the user specific information associated with a view two facilities are provided. Given a view, DU_vToUinfo delivers a pointer to the area of memory that can be used by the user. Given a pointer to an area of memory that was previously obtained through DU_vToUinfo, DU_uInfoToV can be used to obtain the DU_View associated with the uInfo .
The following code fragment demonstrates the use of buffer management facilities.
Click here to see the complete codes. Upon execution this example program produces:
(N-1)-SDU = (N)-PCI + (N)-SDU
The flow of this example program is:
DU_ Module Example Usage Call Graph