@@ -53,6 +53,11 @@ static constexpr const char *ENV_NOLOCK = "DATADIST_NO_MLOCK";
5353static constexpr const char *ENV_SHM_PATH = " DATADIST_SHM_PATH" ;
5454static constexpr const char *ENV_SHM_DELAY = " DATADIST_SHM_DELAY" ;
5555
56+ enum RegionAllocStrategy {
57+ eFindLongest,
58+ eFindFirst
59+ };
60+
5661template <size_t ALIGN = 64 >
5762class RegionAllocatorResource
5863{
@@ -61,8 +66,10 @@ class RegionAllocatorResource
6166 RegionAllocatorResource () = delete ;
6267
6368 RegionAllocatorResource (std::string pSegmentName, FairMQTransportFactory& pShmTrans,
64- std::size_t pSize, std::uint64_t pRegionFlags = 0 , bool pCanFail = false )
69+ std::size_t pSize, const RegionAllocStrategy pStrategy, std::uint64_t pRegionFlags = 0 ,
70+ bool pCanFail = false )
6571 : mSegmentName (pSegmentName),
72+ mStrategy (pStrategy),
6673 mCanFail(pCanFail),
6774 mTransport(pShmTrans)
6875 {
@@ -379,31 +386,47 @@ class RegionAllocatorResource
379386 return false ;
380387 }
381388
382- auto lMaxIter = std::max_element (std::begin (mFreeRanges ), std::end (mFreeRanges ),
383- [](const auto & l, const auto & r) {
384- return (l.first .upper () - l.first .lower ()) < (r.first .upper () - r.first .lower ());
385- });
389+ auto lMaxIter = mFreeRanges .end ();
390+
391+ if (mStrategy == eFindFirst) {
392+ for (auto lInt = mFreeRanges .begin (); lInt != mFreeRanges .end (); ++lInt) {
393+ if (lInt->first .upper () - lInt->first .lower () >= pSize) {
394+ lMaxIter = lInt;
395+ break ;
396+ }
397+ }
398+ } else { /* eFindLongest */
399+ lMaxIter = std::max_element (mFreeRanges .begin (), mFreeRanges .end (),
400+ [](const auto & l, const auto & r) {
401+ return (l.first .upper () - l.first .lower ()) < (r.first .upper () - r.first .lower ());
402+ }
403+ );
404+ }
405+
406+ if (lMaxIter == mFreeRanges .end ()) {
407+ return false ;
408+ }
386409
387410 // check if the size is adequate
388- const auto lFoudSize = lMaxIter->first .upper () - lMaxIter->first .lower ();
389- if (pSize > lFoudSize ) {
411+ const auto lFoundSize = lMaxIter->first .upper () - lMaxIter->first .lower ();
412+ if (pSize > lFoundSize ) {
390413 return false ;
391414 }
392415
393416 if (lMaxIter->second > 1 ) {
394417 EDDLOG (" RegionAllocator BUG: Overlapping interval found: ptr={:p} length={} overlaps={}" ,
395- reinterpret_cast <char *>(lMaxIter->first .lower ()), lFoudSize , lMaxIter->second );
418+ reinterpret_cast <char *>(lMaxIter->first .lower ()), lFoundSize , lMaxIter->second );
396419
397420 // erase this segment
398- mFree -= lFoudSize ;
421+ mFree -= lFoundSize ;
399422 assert (mFree > 0 );
400423 mFreeRanges .erase (lMaxIter);
401424 return false ;
402425 }
403426
404427 // return the extent
405428 mStart = reinterpret_cast <char *>(lMaxIter->first .lower ());
406- mLength = lFoudSize ;
429+ mLength = lFoundSize ;
407430 mFreeRanges .erase (lMaxIter);
408431
409432 {
@@ -448,6 +471,7 @@ class RegionAllocatorResource
448471 std::string mSegmentName ;
449472 std::size_t mSegmentSize ;
450473 std::atomic_bool mRunning = false ;
474+ RegionAllocStrategy mStrategy ;
451475 bool mCanFail = false ;
452476
453477 FairMQTransportFactory &mTransport ;
0 commit comments