Skip to content

Commit a0b9ac5

Browse files
committed
added alignment option and comments
1 parent 947a474 commit a0b9ac5

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

src/MemoryPagesPool.cxx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,57 @@
11
#include "MemoryPagesPool.h"
22

3-
MemoryPagesPool::MemoryPagesPool(size_t vPageSize, size_t vNumberOfPages, void *vBaseAddress, size_t vBaseSize, ReleaseCallback vCallback) {
3+
MemoryPagesPool::MemoryPagesPool(size_t vPageSize, size_t vNumberOfPages, void *vBaseAddress, size_t vBaseSize, ReleaseCallback vCallback, size_t pageAlign) {
4+
// initialize members from parameters
45
pageSize=vPageSize;
56
numberOfPages=vNumberOfPages;
67
baseBlockAddress=vBaseAddress;
78
baseBlockSize=vBaseSize;
8-
releaseBaseBlockCallback=vCallback;
9-
10-
size_t sizeNeeded=pageSize * numberOfPages;
9+
releaseBaseBlockCallback=vCallback;
10+
11+
// if not specified, assuming base block size big enough to fit number of pages * page size
12+
if (baseBlockSize==0) {
13+
baseBlockSize=pageSize * numberOfPages;
14+
}
15+
16+
// compute offset of first page to ensure aligned as requested
17+
size_t offsetFirstPage=0;
18+
if (pageAlign) {
19+
size_t bytesExcess=((size_t)vBaseAddress) % pageAlign;
20+
if (bytesExcess) {
21+
offsetFirstPage=pageAlign-bytesExcess;
22+
}
23+
}
1124

12-
if (vBaseSize==0) {
13-
baseBlockSize=sizeNeeded;
14-
} else if (sizeNeeded>vBaseSize) {
15-
numberOfPages=baseBlockSize/pageSize;
25+
// if necessary, reduce number of pages to fit in available space
26+
size_t sizeNeeded=pageSize * numberOfPages + offsetFirstPage;
27+
if (sizeNeeded>baseBlockSize) {
28+
numberOfPages=(baseBlockSize-offsetFirstPage)/pageSize;
1629
}
1730

31+
// create a fifo and store list of pages available
1832
pagesAvailable=std::make_unique<AliceO2::Common::Fifo<void *>>(numberOfPages);
1933
for (size_t i=0; i<numberOfPages; i++) {
20-
void *ptr=&((char *)baseBlockAddress)[i*pageSize];
34+
void *ptr=&((char *)baseBlockAddress)[offsetFirstPage+i*pageSize];
2135
pagesAvailable->push(ptr);
2236
}
2337
}
2438

2539
MemoryPagesPool::~MemoryPagesPool() {
40+
// if defined, use provided callback to release base block
2641
if ( (releaseBaseBlockCallback != nullptr) && (baseBlockAddress!=nullptr) ) {
2742
releaseBaseBlockCallback(baseBlockAddress);
2843
}
2944
}
3045

3146
void *MemoryPagesPool::getPage() {
47+
// get a page from fifo, if available
3248
void *ptr=nullptr;
3349
pagesAvailable->pop(ptr);
3450
return ptr;
3551
}
3652

3753
void MemoryPagesPool::releasePage(void *address) {
54+
// put back page in list of available pages
3855
pagesAvailable->push(address);
3956
}
4057

@@ -57,8 +74,8 @@ size_t MemoryPagesPool::getBaseBlockSize() {
5774
return baseBlockSize;
5875
}
5976

60-
6177
std::shared_ptr<DataBlockContainer> MemoryPagesPool::getNewDataBlockContainer(void *newPage) {
78+
// get a new page if none provided
6279
if (newPage==nullptr) {
6380
// get a new page from the pool
6481
newPage=getPage();
@@ -67,7 +84,8 @@ std::shared_ptr<DataBlockContainer> MemoryPagesPool::getNewDataBlockContainer(vo
6784
}
6885
}
6986

70-
// fill header
87+
// fill header at beginning of page
88+
// assuming payload is contiguous after header
7189
DataBlock *b=(DataBlock *)newPage;
7290
b->header.blockType=DataBlockType::H_BASE;
7391
b->header.headerSize=sizeof(DataBlockHeaderBase);

src/MemoryPagesPool.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,41 @@
77
#include <Common/DataBlockContainer.h>
88

99

10-
// optimized for 1-1 consumers (1 thread to get the page, 1 thread to release them)
11-
// no check on address of data pages pushed back
12-
// base address should be kept while object in use
10+
// This class creates a pool of data pages from a memory block
11+
// Optimized for 1-1 consumers (1 thread to get the page, 1 thread to release them)
12+
// No check is done on validity of address of data pages pushed back in queue
13+
// Base address should be kept while object is in use
1314

1415

1516
class MemoryPagesPool {
1617

1718
public:
1819

19-
using ReleaseCallback = std::function<void(void*)>;
20+
// prototype of function to release memory block
21+
// argument is the baseAddress provided to constructor
2022
// NB: may use std::bind to add extra arguments
23+
using ReleaseCallback = std::function<void(void*)>;
24+
25+
// constructor
26+
// parameters:
27+
// - size of each page (in bytes)
28+
// - number of pages in the pool
29+
// - base address of memory block where to create the pages
30+
// - size of memory block in bytes (if zero, assuming it is big enough for page number * page size)
31+
// - a release callback to be called at destruction time
32+
// - page align is for alignment of 1st page (all pages are created contiguous)
33+
MemoryPagesPool(size_t pageSize, size_t numberOfPages, void *baseAddress, size_t baseSize=0, ReleaseCallback callback=nullptr, size_t pageAlign=0);
2134

22-
// constructor (args: size of each page and number of pages in the pool, base address where to create the pages)
23-
MemoryPagesPool(size_t pageSize, size_t numberOfPages, void *baseAddress, size_t baseSize=0, ReleaseCallback callback=nullptr);
24-
~MemoryPagesPool(); // destructor
35+
// destructor
36+
~MemoryPagesPool();
2537

38+
// methods to get and release page
39+
// the two functions can be called concurrently without locking
40+
// (but a lock is needed if calling the same function concurrently)
2641
void *getPage(); // get a new page from the pool (if available, nullptr if none)
2742
void releasePage(void *address); // insert back page to the pool after use, to make it available again
2843

44+
// access to variables
2945
size_t getPageSize(); // get the page size
3046
size_t getTotalNumberOfPages(); // get number of pages in pool
3147
size_t getNumberOfPagesAvailable(); //get number of pages currently available
@@ -43,7 +59,7 @@ class MemoryPagesPool {
4359
void * baseBlockAddress; // address of block containing all pages
4460
size_t baseBlockSize; // size of block containing all pages
4561

46-
ReleaseCallback releaseBaseBlockCallback;
62+
ReleaseCallback releaseBaseBlockCallback; // the user function called in destructor, typically to release the baseAddress block.
4763
};
4864

4965

0 commit comments

Comments
 (0)