Memory usage techniques in middleware of a real-time data distribution system

A method of operating real-time middleware associated with at least one node of a data distribution system is provided. At least one pool of a plurality of fixed block size units of memory of the node is allocated (e.g., via an operating system call). Based on loan requests for dynamic memory elements on behalf of a user application executing on the node, an indication of at least one of the allocated fixed block size units to be lent is provided. A list of which allocated fixed block size units are being lent from the pool is maintained, including maintaining the list based on return requests, on behalf of the user application executing on the node, of fixed block size units of the pool. Substantially all of the dynamic memory elements of the real-time middleware associated with the node are provided from the at least one pool of allocated fixed block size units based on the loan requests on behalf of the user application.

CROSS-REFERENCE TO RELATED APPLICATIONS

This application is related to co-pending and concurrently filed application Ser. No. 11/410,563, filed Apr. 24, 2006, entitled “A FRAMEWORK FOR EXECUTING MULTIPLE THREADS AND SHARING RESOURCES IN A MULTITHREADED COMPUTER PROGRAMMING ENVIRONMENT”, by Stephen Jisoo Rhee, Elaine Yee Ting Sin, Gerardo Pardo-Castellote, Stefaan Sonck Thiebaut, and Rajive Joshi, which is incorporated by reference herein for all purposes.

This application is related to co-pending and concurrently filed application Ser. No. 11/410,511, filed Apr. 24, 2006, entitled “FLEXIBLE MECHANISM FOR IMPLEMENTING THE MIDDLEWARE OF A DATA DISTRIBUTION SYSTEM OVER MULTIPLE TRANSPORT NETWORKS”, by Rajive Joshi, Henry Choi, and Gerardo Pardo-Castellote, and Stefaan Sonck Thiebaut, which is incorporated by reference herein for all purposes.

BACKGROUND

Middleware may be used to implement a real-time data distribution system to allow distributed processes to exchange data without concern for the actual physical location or architecture of their peers. The middleware may include support for best-effort and reliable communications. For example, the Object Management Group's (OMG) Data Distribution Service for Real-Time Systems (DDS) is a standard specification for publish-subscribe data-distribution systems. The purpose of the specification is to provide a common application-level interface that clearly defines the data-distribution service.

Referring to the simplified block diagram inFIG. 1, DDS uses a publish-subscribe (P-S) communication model. The P-S communication model employs asynchronous message passing between concurrently operating subsystems. The publish-subscribe model connects anonymous information producers with information consumers. The overall distributed system is composed of processes, each running in a separate address space possibly on different computers. In this patent application, each of these processes of the distributed system is referred to as a “participant application”. A participant application may be a producer or consumer of data, or both.

Using the middleware, data producers declare the topics on which they intend to publish data; data consumers subscribe to the topics of interest. When a data producer publishes some data on a topic, the middleware operates such that all the consumers subscribing to that topic receive it. The data producers and consumers remain anonymous, resulting in a loose coupling of sub-systems, which is well suited for data-centric distributed applications. This is referred to as a DCPS (data-centric publish subscribe) architecture.

The DCPS model employs the concept of a “global data space” of data-objects that any entity can access. Applications that need data from this space declare that they want to subscribe to the data, and applications that want to modify data in the space declare that they want to publish the data. A data-object in the space is uniquely identified by its keys and topic, and each topic has a specific type. There may be several topics of a given type. A global data space is identified by its domain id. Each subscription/publication belongs to the same domain to communicate.

For example, the reader is referred to the Object Management Group's Specification entitled “Data Distribution Service for Real-Time Systems Specification,” Version 1.1, dated December 2005. See http: //www dot omg dot org/docs/formal/05-12-04 dot pdf (referred to herein as “DDS Specification”). In the DDS Specification, a DCPS architecture is specified that includes the following entities: DomainParticipant, DataWriter, DataReader, Publisher, Subscriber, and Topic. All these classes extend Entity, which is an abstract base class for all the DCPS objects that support QoS policies, a listener and a status condition. The particular extension of Entity represents the ability to be configured through QoS policies, be enabled, be notified of events via listener objects, and support conditions that can be waited upon by the application. Each specialization of the Entity base class has a corresponding specialized listener and a set of QoSPolicy values that are suitable to it. SeeFIGS. 2-2(“DCPS conceptual model”) of the DDS Specification.

A Publisher represents the object responsible for data issuance. A Publisher may publish data of different data types. A DataWriter is a typed facade to a publisher; participants use DataWriter(s) to communicate the value of and changes to data of a given type. Once new data values have been communicated to the publisher, it is the Publisher's responsibility to determine when it is appropriate to issue the corresponding message and to actually perform the issuance (the Publisher will do this according to its QoS, or the QoS attached to the corresponding DataWriter, and/or its internal state).

A Subscriber receives published data and makes it available to the participant. A Subscriber may receive and dispatch data of different specified types. To access the received data, the participant must use a typed DataReader attached to the subscriber.

The association of a DataWriter object (representing a publication) with DataReader objects (representing the subscriptions) is done by means of the Topic. A Topic associates a name (unique in the system), a data type, and QoS related to the data itself. The type definition provides enough information for the service to manipulate the data (for example serialize it into a network-format for transmission). The definition can be done by means of a textual language (e.g. something like “float x; float y;”) or by means of an operational “plugin” that provides the necessary methods.

The DDS middleware handles the actual distribution of data on behalf of a user application. The distribution of the data is controlled by user settable Quality of Service (QoS).

Real-time middleware should be characterized by predictable delivery of data. The middleware of a node thus buffers incoming data samples until an application executing on the node retrieves the data samples. In addition, the middleware buffers outgoing data samples, for example, in case they need to be resent to one or more readers according to an applicable QoS. Storing data samples requires memory, and the amount needed changes dynamically.

SUMMARY

In accordance with an aspect, a method of operating real-time middleware associated with at least one node of a data distribution system is provided. At least one pool of a plurality of fixed block size units of memory of the node is allocated (e.g., via an operating system call). Based on loan requests for dynamic memory elements on behalf of a user application executing on the node, an indication of at least one of the allocated fixed block size units to be lent is provided. A list of which allocated fixed block size units are being lent from the pool is maintained, including maintaining the list based on return requests, on behalf of the user application executing on the node, of fixed block size units of the pool. Substantially all of the dynamic memory elements of the real-time middleware associated with the node are provided from the at least one pool of allocated fixed block size units based on the loan requests on behalf of the user application.

In accordance with another aspect, a method of communicating data samples by middleware associated with at least one node of a data distribution system is provided. The method includes storing the data samples in memory of the node in fixed block size units. A list is maintained in memory of the node in fixed block size units, each entry in the list corresponding to a separate one of the data samples. An index data structure is maintained including a plurality of instance lists, in memory of the node in fixed block size units, each instance list corresponding to a separate data-object instance within the node and each entry of each instance list corresponding to a data sample for the data-object instance to which that instance list corresponds. The memory of fixed block size units is borrowed and returned, as appropriate, to at least one memory buffer pool associated with the node.

DETAILED DESCRIPTION

It is desired to minimize or avoid memory operations that can affect the timeliness of data delivery in a real-time data distribution system. Typically, memory is allocated dynamically by an operating system. In general, not only is dynamic allocation/deallocation of memory an expensive operation, but it also takes a varying (i.e., unpredictable) amount of time. Also, dynamic memory allocation/deallocation can result in memory fragmentation, such that the available contiguous memory is less than a certain size, which can exhaust memory for larger size blocks even though there is enough total memory available. These characteristics detract from real-time operation.

In accordance with an aspect, the middleware acts such that it is allocated large blocks of memory, and the middleware controls the use of that allocated memory by threads of the middleware, such that the allocated memory can be used in a predictable way. More particularly, the middleware “lends” fixed-size blocks of the allocated memory to the threads. The thread then “returns” the lent fixed-size blocks at a later time as appropriate. For example, if a fixed-size block holds a sample to be published, the fixed-size block may be returned when all consumers acknowledge receipt of the sample, if the quality of service policy attached to the publication requires reliable publication. As another example, the fixed-size block holding a sample to be published may be returned upon publication of the sample (without regard for acknowledgement of receipt) if the quality of service policy attached to the publication is best-effort.

In summary, a predictable memory management scheme and architecture is described including one or more of the following elements. First, a fast memory manager for fixed size buffers (referred to as a “FastBuffer”) is described. Also described is an organization of all the dynamic memory in the middleware as fixed size memory blocks that can be managed as separate FastBuffers. For example, the use of FastBuffers for all user data and samples is described. A particular implementation is described as well, namely a data structure and algorithms for sample management that is organized around the FastBuffer scheme.

Turning now toFIG. 2, the FastBuffer scheme for allocating, lending and returning fixed-size memory blocks is described. A FastBuffer200includes a pool202of fixed size memory buffers204. The pool202is comprised of the large block of allocated memory. The FastBuffer200maintains an array206of buffer pointers208, each capable of holding a pointer to one of the fixed size memory buffers of the pool202, a counter of how many buffers are available, and a moving ‘pointer’210to the next available buffer in the pool.

When a FastBuffer200is created, the array206of buffer pointers208is filled up so that each member of the array206points to an available buffer204in the pool. At runtime, one or more buffers204can be requested by a thread of the middleware. The requested buffer204is loaned to the thread and, when the thread is finished using the borrowed buffer204, that buffer204is returned back to the FastBuffer200.

When the FastBuffer200loans a buffer to a thread, the internal moving pointer210to the array206of buffer pointers208is decremented, and the next available buffer204(as indicated by the particular buffer point208pointed to by the internal moving pointer210) is lent to the requesting thread. When the thread returns the lent buffer204back to the FastBuffer200, that buffer204becomes the next available buffer204to be lent, and the internal moving pointer210to the array of buffers202is incremented and the returned buffer204is added to the array206of buffer pointers.

Thus, chunks of memory can be allocated/deallocated in constant time, without involvement of unpredictable operating system. In general, a FastBuffer200is characterized by three parameters—M, N and P. M indicates the number of initial buffers204in the buffer pool202. N indicates the size in bytes of each buffer204. Finally, P is an indication of the growth policy associated with the buffer pool202. That is, P indicates how many additional N-byte size buffers204should be allocated when required. The FastBuffer scheme includes detecting when a predetermined condition is met—i.e., when additional buffers204are to be allocated. This may be, for example, when the number of available (i.e., not lent) buffers204goes down to a threshold number (which may even be zero).

A growth policy (denoted by reference numerals212aand212b) can be specified with the FastBuffer scheme, to specify how the pool of available buffers should be expanded when all the buffers are on loan and additional buffers are desired by the users. Additional ‘P’ buffers (212b) can be added to the pool202by allocating P*N bytes from the operating-system (OS), as well as adding P new pointers208to the array206of buffer pointers.

‘P’ can be specified in a variety of ways including, for example:P=0, i.e. a no growth policy. When all the buffers are exhausted the caller will see an ‘out of resources’ condition.P=fixed number, i.e. a linear growth policy. A fixed number of buffers are injected into the pool when it is exhausted (or the requirement for new buffers is otherwise met, as discussed above)P=current number of buffers, i.e. exponential growth policy. The pool is doubled when it is exhausted (or the requirement for new buffers is otherwise met, as discussed above)

Having described an example of the FastBuffer scheme, we now discuss generally how real-time tasks can use the FastBuffer scheme to access memory quickly and in a predictable manner. As discussed above, the normal memory-allocation routines (such as malloc and free) are relatively slow routines and may be too time-consuming for real-time tasks. Furthermore, the time for these routines is not predictable. By using the FastBuffer scheme, real-time tasks can access memory quickly.

In one example, to use the FastBuffer scheme, the FastBufferPool_new routine is called (typically during initialization). This will pre-allocate a specified number (M) of buffers, each of a specified size (N bytes) from the OS. At run time, a task can borrow a buffer by calling FastBufferPool_getBuffer. The caller can use the buffer for its purposes for as long as necessary and then return the buffer by calling FastBufferPool_returnBuffer. If, when using getBuffer, the FastBufferPool runs out of buffers, it will allocate a block of additional buffers from the OS. The number of additional buffers that will be allocated is user configurable via a growth policy. FastBufferPool_returnBuffer will cause the buffer to the FastBufferPool but will not dynamically return memory to the OS. The getBuffer( ) and the returnBuffer( ) routines operate quickly and in constant time (for getBuffer( ) if no growth was necessary or allowed), thus making the memory allocation/deallocation fast and predictable from the perspective of the caller.

With reference toFIG. 3, we now describe a general methodology for using the FastBuffer scheme in a real-time middleware implementation. (Later, we describe a particular application of this general methodology, to sample handling.) An efficient and predictable real-time middleware implementation can be realized by using the FastBuffer scheme for all dynamic memory data structures. A real-time middleware implementation may be developed in layers. Some organizing principles for using the FastBuffer methodology, in one example, for a real-time middleware implementation are now discussed. It should be noted that, while these are discussed as organizing principles, they should not be viewed as limiting the invention as set forth in the claims.

One principle is that substantially all of the internal dynamic memory data structures used by the middleware have a fixed block size. The middleware uses only multiples of the fixed size data structures—no variable-sized data structures.

Another principle is that each dynamic memory data structure is associated with its own FastBuffer. When new instances of the data structure are needed, the new instances are obtained from the FastBuffer pool. When the instances are no longer needed, the instances are returned back to the FastBuffer pool.

Another principle, illustrated inFIG. 3, is that multiple FastBuffer parameters are mapped parametrically to define a data structure such that not all of the resource parameters need be explicitly defined (either by a user application, or by a default). Rather, a set of resource parameters may be parametrically defined based on another set of resource parameters that is explicitly defined or may even have been itself parametrically defined.

This parametric definition of resource parameters may be particularly useful in conjunction with a middleware implementation that is configured in layers, such as that shown in theFIG. 4block architecture diagram. In this way, multiple FastBuffer parameters in a lower layer can be parametrically defined as a function of resource parameters at a higher layer, and the data structure can be exposed to the user application by means of memory usage Quality of Service (QoS) policies407. The hierarchical mapping scheme addresses what might otherwise be an explosion in FastBuffer parameters and an ensuing configuration complexity for the user. Rather, the user application code need only consider a relatively small set of well-understood configuration policies.

Using theFIG. 4example, the user application code402may only provide FastBuffer configuration parameters to the Middleware405via the Middleware API404. For example, the Middleware API may include the OMG DDS API specification for real-time data distribution. FastBuffer configuration parameters for use in lower layers (e.g., any of layers406,408,410,412and414) of the Middleware may be defined parametrically based directly or indirectly on the configuration parameters provided from the user application code402. Typically, the layers are organized hierarchically and have well-defined interfaces between them, such that configuration parameters provided from one layer to another layer are provided through any intervening layers via those well-defined interfaces.

Referring toFIG. 3, generically, the user application configures the parameters M, N and P (denoted by302M,302N and302P—generally,302) at the interface to Layer B. Within the definition of Layer B, the resource parameters M, N and P for FastBuffer1_B are internally defined (e.g., are fixed to a default value, or are parametrically defined as a function of the parameters M, N and P302provided by the user application at the interface to Layer B) and need not be configured by the user application. In fact, the resource parameters M, N and P for FastBuffer1_B are typically not even accessible to the user application. Similarly, the resource parameters M, N and P for FastBuffer2_B and up to FastBuffer K_B are internally defined.

In addition, the resource parameters M, N and P (304M,304N and304P—generally,304) are provided from Layer B to Layer A at the interface between Layer B and Layer A. These resource parameters304are internally defined within Layer B and provided to Layer A. The resource parameters M, N and P for FastBuffer1_A to FastBuffer K_A are provided in a manner similar to that discussed above with respect to the resource parameters M, N and P for FastBuffer1_B to FastBuffer K_B. WhileFIGS. 3 and 4illustrate parametric definition of parameters across layers, such parametric definition need not be across layers and, for example, may be within a particular layer as well.

Using this organizational technique can have benefits that can be critical to real-time middleware implementation. For example, the middleware can pre-allocate all the dynamic memory it is going to need during its operation. A user can limit the dynamic memory usage to predetermined amounts, which can be especially useful in resource constrained environments. Furthermore, the middleware dynamic memory usage can be configured by the user to follow a well-defined growth policy. The memory already in use continues to be used, while additional memory can be added for use by the middleware as needed to support the user application code.

It can also be seen that middleware implementation that use the FastBuffer implementation do not depend on any platform-specific memory management scheme. This allows the middleware code to be easily ported, even to environments that may not support dynamic memory in the OS.

We now discuss a particular example of middleware implementation using the FastBuffer scheme for sample management. As discussed above, samples are the data items distributed in a DCPS (data-centric publish subscribe) architecture. In general, data samples are stored in internal buffers, by the middleware on behalf of a user publisher application, to realize a particular quality of service (QoS), for example, as requested or assumed by the user publisher application. Furthermore, samples are stored in internal buffers, by the middleware, on behalf of a user consumer application until the user consumer application can actually consume the samples. In either case (publisher or consumer), the samples can be purged when they are no longer needed.

More specifically, data samples are stored in FastBuffers, and assigned a sequence number to be used when organized into a list. The list is referred to as a ‘Queue’ as it largely has queue-like semantics, e.g. first-in first-out. Referring toFIG. 5as an example, each entry in the Queue502points to sample buffers504that holds the actual data sample. A sample belongs to exactly one data-object instance, and is accessed by data-object instance for some of the QoS. A separate keyed list is used for this purpose, which is referred to as an ‘Index’506. The Index506indexes the samples in the sample buffer504, referred to by the entries of the Queue502, in a potentially different order by sorting the samples by instance. Separate data-object instances are referred to inFIG. 5by reference numerals508a,508band508c.

Each data-object instance508has an associated key, and is also associated with one or more sample entries in the Queue502. The Index506entries and the Queue502entries can be allocated from one or more FastBuffer pools that are separate from the FastBuffer pools that are allocated for the data samples (i.e., Sample Buffers504). It is also possible for the Index506entries and the Queue502entries to be either distinct entities (i.e., with distinct resource controls M, N and P for each) with one pointing to the other or to be realized by a single entity containing both control structures.

The overall organization illustrated inFIG. 5is referred to as a ‘Writer Collator,’ since it supports efficient access to a data sample by the data-object key (i.e. is collated by data-object instance508by the Index506) in addition to by the sample sequence number via the Queue502. For example, outgoing data samples (in Sample Buffers504) are organized using a Writer Collator structure where the sample sequence number is assigned in increasing order at write-time (via Queue502, each entry pointing to a separate sample in Sample Buffers504), but the samples are collated by instance508(via Index506), as discussed above.

FIG. 6illustrates the overall organization of an architecture of FastBuffer structures to organize input samples, including collating the input samples by data-object instance. The input samples are held in the Sample Buffers604, and each entry in a Queue602points to a separate one of the Sample Buffers604. In addition, an Index606indexes the samples in the Sample Buffer604, referred to by the entries of the Queue602, in a potentially different order by sorting the samples by data-object instance. Separate instances are referred to inFIG. 6by reference numerals608a,608band608c.

Referring toFIG. 7, in some examples, there is one more level of buffer management involved for incoming data samples. This helps to manage the incoming communications for reliability considerations. Typically, user applications expect incoming samples to be delivered “in-order.” However, in actual practice, the samples may be received by the middleware associated with a consumer application in a different order than the one in which the samples were sent by the middleware associated with a producer application.

Therefore, an additional level of buffer management may include a ‘Remote Writer Queue’ maintained, in the middleware that includes a Reader, for each ‘Remote Writer’ from which the Reader receives data samples. For example,FIG. 7illustrates two Remote Writer Queues702aand702b. The potentially out of order incoming samples are inserted into the appropriate Remote Writer Queue702aor702b, according to the Remote Writer. That is, the insertion is according to the sequence numbers of the samples provided from the Remote Writer side, which are kept there until missing gaps are filled. As gaps are filled, the samples are moved, or “committed”, into the Reader Collator's Queue602(FIG. 6), at which time the samples are assigned an increasing sequence number on the Reader's side.

It should be noted that neither the samples nor the entries need be copied; instead the entries from the RemoteWriterQueue can be associated with the Queue602by having the physical entry structure contain the control information for associating with either queue (i.e., one or the Remote Writer Queues702aand702b, or the Queue602). Thus, extra memory allocation and copies may be avoided. Use of the queue per remote writer as a staging area can server other purposes as well, such as fragment assembly, coherent change grouping, and suspending and/or resuming updates to the reader.

As with the structure to organize output data samples illustrated inFIG. 5, the various portions of theFIG. 6structure to organize input data samples may be allocated from various FastBuffer pools. Furthermore, entries in the Remote Writer Queues702aand702bmay also be allocated from yet different FastBuffer pools from those for the data samples. For each FastBuffer used in the manner just discussed, the parameters of the FastBuffer may be exposed to the application via QosPolicies on a DataReader or DataWriter. Thus the application can control the size of the internal buffers and specify different growth policies as appropriate. As discussed above with reference toFIG. 3, the various FastBuffer pools would typically be organized hierarchically.

We now discuss, with reference toFIG. 8, an example of committing a sample to the Reader Collator's Queue602. The Remote Writer Queue802is an example of a Remote Write Queue such as the Remote Writer Queue702aor702binFIG. 7. At the left side ofFIG. 8, the Remote Writer Queue802is shown in a “before” state—i.e., before the sample #3has been committed to the Queue804(which is an example of the Queue602inFIG. 6). The notation “sample #x” is a shorthand notation to show the order in which the samples were sent from a producer application. That is, “x” is a sequence number of the sample. Since, in the “before” state, sample #1and sample #2have already been committed to the Queue802, sample #3can be committed to the Queue802as well.

At the right side ofFIG. 8, the Remote Write Queue802is shown an “after” state—i.e., after the sample #3has been committed to the Queue804. As can be seen fromFIG. 8, the difference between the “before” state and the “after” state is that the Queue802in the “after” state includes an entry that links to the sample #3. As discussed above, the act of committing the sample, in some examples, does not include copying the sample to a different buffer but, rather, includes reusing the same entry that links to the buffer in which sample #3is held by moving it from the Remote Writer Queue802to the Queue804.

Also, in the “after” state, the entry in the Remote Writer Queue802that was pointing to sample #3in the “before” state is no longer required to be in the Remote Writer Queue802. As also discussed above, the memory associated with the entry may not be returned to a FastBuffer but, rather, the pointers in the entries of the Remote Writer Queue802and of the Queue804may be manipulated so that the entry pointing to sample #3becomes associated with the Queue804and disassociated with the Remote Writer Queue802.

FIGS. 9A-Billustrate a computer system, which is suitable for implementing the embodiments of the present invention.FIGS. 9A and 9Billustrate a computer system1300, which is suitable for implementing embodiments of the present invention.FIG. 9Ashows one possible physical form of the computer system. Of course, the computer system may have many physical forms ranging from an integrated circuit, a printed circuit board, and a small handheld device up to a huge super computer. Computer system1300includes a monitor1302, a display1304, a housing1306, a disk drive1308, a keyboard1310, and a mouse1312. Disk1314is a computer-readable medium used to transfer data to and from computer system1300.

FIG. 9Bis an example of a block diagram for computer system1300. Attached to system bus1320is a wide variety of subsystems. Processor(s)1322(also referred to as central processing units, or CPUs) are coupled to storage devices, including memory1324. Memory1324includes random access memory (RAM) and read-only memory (ROM). As is well known in the art, ROM acts to transfer data and instructions uni-directionally to the CPU and RAM is used typically to transfer data and instructions in a bi-directional manner. Both of these types of memories may include any suitable of the computer-readable media described below. A fixed disk1326is also coupled bi-directionally to CPU1322; it provides additional data storage capacity and may also include any of the computer-readable media described below. Fixed disk1326may be used to store programs, data, and the like and is typically a secondary storage medium (such as a hard disk) that is slower than primary storage. It will be appreciated that the information retained within fixed disk1326may, in appropriate cases, be incorporated in standard fashion as virtual memory in memory1324. Removable disk1314may take the form of any of the computer-readable media described below.

CPU1322is also coupled to a variety of input/output devices, such as display1304, keyboard1310, mouse1312, and speakers1330. In general, an input/output device may be any of: video displays, track balls, mice, keyboards, microphones, touch-sensitive displays, transducer card readers, magnetic or paper tape readers, tablets, styluses, voice or handwriting recognizers, biometrics readers, or other computers. CPU1322optionally may be coupled to another computer or telecommunications network using network interface1340. With such a network interface, it is contemplated that the CPU might receive information from the network, or might output information to the network in the course of performing the above-described method steps. Furthermore, method embodiments of the present invention may execute solely upon CPU1322or may execute over a network such as the Internet in conjunction with a remote CPU that shares a portion of the processing.

In summary, by pre-allocating one or more pools of memory for the real-time middleware and then allowing the execution threads to “borrow” and “return” blocks of the memory to the pool, timeliness and predictability of data delivery in the real-time middleware can be more adequately ensured. In addition, the characteristics of the one or more pools of memory may be configurable by the user application, including a growth policy for the pool of memory. Furthermore, by employing layers of abstraction in the use of the pools of memory, configuration of the pools may be quite sophisticated, while shielding the user application from having deal with much of the complexity of the configuration (e.g., setting configuration parameters). The pre-allocated memory pools of fixed size buffers are used for implementing a fast, low-latency sample management mechanism in the outgoing data path for a Data Writer, and the incoming data path for a Data Reader.