BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_concurrentfixedpool

Functions

void * operator new (bsl::size_t size, BloombergLP::bdlma::ConcurrentFixedPool &pool)
 
void operator delete (void *address, BloombergLP::bdlma::ConcurrentFixedPool &pool)
 

Detailed Description

Outline

Purpose

Provide thread-safe pool of limited # of blocks of uniform size.

Classes

See also
bdlma_concurrentpool

Description

This component implements a fully thread-safe memory pool that allocates and manages a limited number (specified at construction) of memory blocks of some uniform size (also specified at construction). A bdlma::ConcurrentFixedPool constructed to manage up to N blocks also provides an association between the address of each block and an index in the range [ 0 .. N - 1 ].

Other than this mapping between block and index, and the associated limit on the maximum number of blocks that may be simultaneously allocated, this component's semantics are identical to bdlma::ConcurrentPool. In particular, this component overloads global operator new in the same manner, and the behaviors of release and reserveCapacity are equivalent to the corresponding methods in bdlma::ConcurrentPool.

Like bdlma::ConcurrentPool, this component is intended to be used to implement out-of-place container classes that hold elements of uniform size.

Usage

This section illustrates intended use of this component.

Example 1: Basic Usage

bdlma::ConcurrentFixedPool is intended to implement out-of-place container classes that hold up to a fixed number of elements, all of uniform size. Suppose we wish to implement a simple thread pool. We want the equivalent of a bsl::deque<bsl::function<void(void)> >. However, to minimize the time spent performing operations on this deque - which must be carried out under a lock - we instead store just pointers in the deque, and manage memory efficiently using bdlma::ConcurrentFixedPool. bdlma::ConcurrentFixedPool is fully thread-safe and does not require any additional synchronization.

The example below is just for the container portion of our simple thread pool. The implementation of the worker thread, and the requisite synchronization, are omitted for clarity.

class my_JobQueue {
public:
// PUBLIC TYPES
typedef bsl::function<void(void)> Job;
private:
// DATA
bslmt::Mutex d_lock;
bslma::Allocator *d_allocator_p;
// Not implemented:
my_JobQueue(const my_JobQueue&);
public:
// CREATORS
my_JobQueue(int maxJobs, bslma::Allocator *basicAllocator = 0);
~my_JobQueue();
// MANIPULATORS
void enqueueJob(const Job& job);
int tryExecuteJob();
};
my_JobQueue::my_JobQueue(int maxJobs, bslma::Allocator *basicAllocator)
: d_queue(basicAllocator)
, d_pool(sizeof(Job), maxJobs, basicAllocator)
, d_allocator_p(bslma::Default::allocator(basicAllocator))
{
}
my_JobQueue::~my_JobQueue()
{
Job *jobPtr;
while (!d_queue.empty()) {
jobPtr = d_queue.front();
jobPtr->~Job();
d_queue.pop_front();
}
}
void my_JobQueue::enqueueJob(const Job& job)
{
Job *jobPtr = new (d_pool) Job(job, d_allocator_p);
d_lock.lock();
d_queue.push_back(jobPtr);
d_lock.unlock();
}
int my_JobQueue::tryExecuteJob()
{
d_lock.lock();
if (d_queue.empty()) {
d_lock.unlock();
return -1; // RETURN
}
Job *jobPtr = d_queue.front();
d_queue.pop_front();
d_lock.unlock();
(*jobPtr)();
d_pool.deleteObject(jobPtr);
return 0;
}
Definition bdlma_concurrentfixedpool.h:209
Definition bslstl_deque.h:772
Forward declaration.
Definition bslstl_function.h:934
Definition bslma_allocator.h:457
Definition bslmt_mutex.h:315
Definition balxml_encoderoptions.h:68

Note that in the destructor, there is no need to deallocate the individual job objects - the destructor of bdlma::ConcurrentFixedPool will release any remaining allocated memory. However, it is necessary to invoke the destructors of all these objects, as the destructor of bdlma::ConcurrentFixedPool will not do so.

Function Documentation

◆ operator delete()

void operator delete ( void *  address,
BloombergLP::bdlma::ConcurrentFixedPool &  pool 
)
inline

Use the specified pool to deallocate the memory at the specified address. The behavior is undefined unless address was allocated using pool and has not already been deallocated. This operator is supplied solely to allow the compiler to arrange for it to be called in case of an exception. Client code should not call it; use bdlma::ConcurrentFixedPool::deleteObject() instead.

◆ operator new()

void * operator new ( bsl::size_t  size,
BloombergLP::bdlma::ConcurrentFixedPool &  pool 
)
inline

Allocate memory of the specified size bytes from the specified pool, and return the address of the allocated memory. The behavior is undefined unless size is the same as the objectSize with which pool was constructed. Note that an object may allocate additional memory internally within its constructor, requiring the allocator to be passed in as a constructor argument:

my_Type *newMyType(bdlma::ConcurrentFixedPool *pool,
bslma::Allocator *basicAllocator) {
return new (*pool) my_Type(..., basicAllocator);
}

Note also that the analogous version of operator delete should not be called directly. Instead, this component provides a template member function bdlma::ConcurrentFixedPool::deleteObject parameterized by TYPE that performs the equivalent of the following:

void deleteMyType(bdlma::ConcurrentFixedPool *pool, my_Type *t) {
t->~my_Type();
pool->deallocate(t);
}
void deallocate(void *address)