mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 16:46:47 +00:00
Shm: configurable allocation strategy
This commit is contained in:
parent
3b2d2a0ac8
commit
73109fe6d3
|
@ -38,6 +38,7 @@ void Sampler::InitTask()
|
||||||
|
|
||||||
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
||||||
LOG(info) << "Region event: " << info.event
|
LOG(info) << "Region event: " << info.event
|
||||||
|
<< ", managed: " << info.managed
|
||||||
<< ", id: " << info.id
|
<< ", id: " << info.id
|
||||||
<< ", ptr: " << info.ptr
|
<< ", ptr: " << info.ptr
|
||||||
<< ", size: " << info.size
|
<< ", size: " << info.size
|
||||||
|
|
|
@ -31,6 +31,7 @@ void Sink::InitTask()
|
||||||
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
fMaxIterations = fConfig->GetProperty<uint64_t>("max-iterations");
|
||||||
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
fChannels.at("data").at(0).Transport()->SubscribeToRegionEvents([](FairMQRegionInfo info) {
|
||||||
LOG(info) << "Region event: " << info.event
|
LOG(info) << "Region event: " << info.event
|
||||||
|
<< ", managed: " << info.managed
|
||||||
<< ", id: " << info.id
|
<< ", id: " << info.id
|
||||||
<< ", ptr: " << info.ptr
|
<< ", ptr: " << info.ptr
|
||||||
<< ", size: " << info.size
|
<< ", size: " << info.size
|
||||||
|
|
|
@ -28,21 +28,24 @@ enum class FairMQRegionEvent : int
|
||||||
struct FairMQRegionInfo
|
struct FairMQRegionInfo
|
||||||
{
|
{
|
||||||
FairMQRegionInfo()
|
FairMQRegionInfo()
|
||||||
: id(0)
|
: managed(true)
|
||||||
|
, id(0)
|
||||||
, ptr(nullptr)
|
, ptr(nullptr)
|
||||||
, size(0)
|
, size(0)
|
||||||
, flags(0)
|
, flags(0)
|
||||||
, event(FairMQRegionEvent::created)
|
, event(FairMQRegionEvent::created)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FairMQRegionInfo(uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
|
FairMQRegionInfo(bool _managed, uint64_t _id, void* _ptr, size_t _size, int64_t _flags, FairMQRegionEvent _event)
|
||||||
: id(_id)
|
: managed(_managed)
|
||||||
|
, id(_id)
|
||||||
, ptr(_ptr)
|
, ptr(_ptr)
|
||||||
, size(_size)
|
, size(_size)
|
||||||
, flags(_flags)
|
, flags(_flags)
|
||||||
, event(_event)
|
, event(_event)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool managed; // managed/unmanaged
|
||||||
uint64_t id; // id of the region
|
uint64_t id; // id of the region
|
||||||
void* ptr; // pointer to the start of the region
|
void* ptr; // pointer to the start of the region
|
||||||
size_t size; // region size
|
size_t size; // region size
|
||||||
|
|
|
@ -69,6 +69,7 @@ Plugin::ProgOptions ConfigPluginProgramOptions()
|
||||||
("max-run-time", po::value<uint64_t >()->default_value(0), "Maximum runtime for the Running state handler, after which state will change to Ready (in seconds, 0 for no limit).")
|
("max-run-time", po::value<uint64_t >()->default_value(0), "Maximum runtime for the Running state handler, after which state will change to Ready (in seconds, 0 for no limit).")
|
||||||
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
||||||
("shm-segment-size", po::value<size_t >()->default_value(2ULL << 30), "Shared memory: size of the shared memory segment (in bytes).")
|
("shm-segment-size", po::value<size_t >()->default_value(2ULL << 30), "Shared memory: size of the shared memory segment (in bytes).")
|
||||||
|
("shm-allocation", po::value<string >()->default_value("rbtree_best_fit"), "Shared memory allocation algorithm: rbtree_best_fit/simple_seq_fit.")
|
||||||
("shm-mlock-segment", po::value<bool >()->default_value(false), "Shared memory: mlock the shared memory segment after initialization.")
|
("shm-mlock-segment", po::value<bool >()->default_value(false), "Shared memory: mlock the shared memory segment after initialization.")
|
||||||
("shm-zero-segment", po::value<bool >()->default_value(false), "Shared memory: zero the shared memory segment memory after initialization.")
|
("shm-zero-segment", po::value<bool >()->default_value(false), "Shared memory: zero the shared memory segment memory after initialization.")
|
||||||
("shm-throw-bad-alloc", po::value<bool >()->default_value(true), "Throw a fair::mq::MessageBadAlloc if cannot allocate a message (retry if false).")
|
("shm-throw-bad-alloc", po::value<bool >()->default_value(true), "Throw a fair::mq::MessageBadAlloc if cannot allocate a message (retry if false).")
|
||||||
|
|
|
@ -19,8 +19,11 @@
|
||||||
#include <boost/interprocess/containers/map.hpp>
|
#include <boost/interprocess/containers/map.hpp>
|
||||||
#include <boost/interprocess/containers/string.hpp>
|
#include <boost/interprocess/containers/string.hpp>
|
||||||
#include <boost/interprocess/containers/vector.hpp>
|
#include <boost/interprocess/containers/vector.hpp>
|
||||||
|
#include <boost/interprocess/indexes/null_index.hpp>
|
||||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||||
|
#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -32,6 +35,17 @@ namespace mq
|
||||||
namespace shmem
|
namespace shmem
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct SharedMemoryError : std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
|
||||||
|
using SimpleSeqFitSegment = boost::interprocess::basic_managed_shared_memory<char,
|
||||||
|
boost::interprocess::simple_seq_fit<boost::interprocess::mutex_family>,
|
||||||
|
boost::interprocess::null_index>;
|
||||||
|
// boost::interprocess::iset_index>;
|
||||||
|
using RBTreeBestFitSegment = boost::interprocess::basic_managed_shared_memory<char,
|
||||||
|
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>,
|
||||||
|
boost::interprocess::null_index>;
|
||||||
|
// boost::interprocess::iset_index>;
|
||||||
|
|
||||||
using SegmentManager = boost::interprocess::managed_shared_memory::segment_manager;
|
using SegmentManager = boost::interprocess::managed_shared_memory::segment_manager;
|
||||||
using VoidAlloc = boost::interprocess::allocator<void, SegmentManager>;
|
using VoidAlloc = boost::interprocess::allocator<void, SegmentManager>;
|
||||||
using CharAlloc = boost::interprocess::allocator<char, SegmentManager>;
|
using CharAlloc = boost::interprocess::allocator<char, SegmentManager>;
|
||||||
|
@ -39,6 +53,12 @@ using Str = boost::interprocess::basic_string<char, std::char_traits<
|
||||||
using StrAlloc = boost::interprocess::allocator<Str, SegmentManager>;
|
using StrAlloc = boost::interprocess::allocator<Str, SegmentManager>;
|
||||||
using StrVector = boost::interprocess::vector<Str, StrAlloc>;
|
using StrVector = boost::interprocess::vector<Str, StrAlloc>;
|
||||||
|
|
||||||
|
enum class AllocationAlgorithm : int
|
||||||
|
{
|
||||||
|
rbtree_best_fit,
|
||||||
|
simple_seq_fit
|
||||||
|
};
|
||||||
|
|
||||||
struct RegionInfo
|
struct RegionInfo
|
||||||
{
|
{
|
||||||
RegionInfo(const VoidAlloc& alloc)
|
RegionInfo(const VoidAlloc& alloc)
|
||||||
|
@ -65,6 +85,19 @@ using Uint64RegionInfoPairAlloc = boost::interprocess::allocator<std::pair<const
|
||||||
using Uint64RegionInfoMap = boost::interprocess::map<uint64_t, RegionInfo, std::less<uint64_t>, Uint64RegionInfoPairAlloc>;
|
using Uint64RegionInfoMap = boost::interprocess::map<uint64_t, RegionInfo, std::less<uint64_t>, Uint64RegionInfoPairAlloc>;
|
||||||
using Uint64RegionInfoHashMap = boost::unordered_map<uint64_t, RegionInfo, boost::hash<uint64_t>, std::equal_to<uint64_t>, Uint64RegionInfoPairAlloc>;
|
using Uint64RegionInfoHashMap = boost::unordered_map<uint64_t, RegionInfo, boost::hash<uint64_t>, std::equal_to<uint64_t>, Uint64RegionInfoPairAlloc>;
|
||||||
|
|
||||||
|
struct SegmentInfo
|
||||||
|
{
|
||||||
|
SegmentInfo(AllocationAlgorithm aa)
|
||||||
|
: fAllocationAlgorithm(aa)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AllocationAlgorithm fAllocationAlgorithm;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Uint64SegmentInfoPairAlloc = boost::interprocess::allocator<std::pair<const uint64_t, SegmentInfo>, SegmentManager>;
|
||||||
|
using Uint64SegmentInfoMap = boost::interprocess::map<uint64_t, SegmentInfo, std::less<uint64_t>, Uint64SegmentInfoPairAlloc>;
|
||||||
|
using Uint64SegmentInfoHashMap = boost::unordered_map<uint64_t, SegmentInfo, boost::hash<uint64_t>, std::equal_to<uint64_t>, Uint64SegmentInfoPairAlloc>;
|
||||||
|
|
||||||
struct DeviceCounter
|
struct DeviceCounter
|
||||||
{
|
{
|
||||||
DeviceCounter(unsigned int c)
|
DeviceCounter(unsigned int c)
|
||||||
|
@ -153,6 +186,101 @@ inline std::string buildShmIdFromSessionIdAndUserId(const std::string& sessionId
|
||||||
return shmId;
|
return shmId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SegmentSize : public boost::static_visitor<size_t>
|
||||||
|
{
|
||||||
|
template<typename S>
|
||||||
|
size_t operator()(S& s) const { return s.get_size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentAddress : public boost::static_visitor<void*>
|
||||||
|
{
|
||||||
|
template<typename S>
|
||||||
|
void* operator()(S& s) const { return s.get_address(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentMemoryZeroer : public boost::static_visitor<>
|
||||||
|
{
|
||||||
|
template<typename S>
|
||||||
|
void operator()(S& s) const { s.zero_free_memory(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentFreeMemory : public boost::static_visitor<size_t>
|
||||||
|
{
|
||||||
|
template<typename S>
|
||||||
|
size_t operator()(S& s) const { return s.get_free_memory(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentHandleFromAddress : public boost::static_visitor<boost::interprocess::managed_shared_memory::handle_t>
|
||||||
|
{
|
||||||
|
SegmentHandleFromAddress(const void* _ptr) : ptr(_ptr) {}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
boost::interprocess::managed_shared_memory::handle_t operator()(S& s) const { return s.get_handle_from_address(ptr); }
|
||||||
|
|
||||||
|
const void* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentAddressFromHandle : public boost::static_visitor<void*>
|
||||||
|
{
|
||||||
|
SegmentAddressFromHandle(const boost::interprocess::managed_shared_memory::handle_t _handle) : handle(_handle) {}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
void* operator()(S& s) const { return s.get_address_from_handle(handle); }
|
||||||
|
|
||||||
|
const boost::interprocess::managed_shared_memory::handle_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentAllocate : public boost::static_visitor<void*>
|
||||||
|
{
|
||||||
|
SegmentAllocate(const size_t _size) : size(_size) {}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
void* operator()(S& s) const { return s.allocate(size); }
|
||||||
|
|
||||||
|
const size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentAllocateAligned : public boost::static_visitor<void*>
|
||||||
|
{
|
||||||
|
SegmentAllocateAligned(const size_t _size, const size_t _alignment) : size(_size), alignment(_alignment) {}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
void* operator()(S& s) const { return s.allocate_aligned(size, alignment); }
|
||||||
|
|
||||||
|
const size_t size;
|
||||||
|
const size_t alignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentBufferShrink : public boost::static_visitor<char*>
|
||||||
|
{
|
||||||
|
SegmentBufferShrink(const size_t _old_size, const size_t _new_size, char* _local_ptr)
|
||||||
|
: old_size(_old_size)
|
||||||
|
, new_size(_new_size)
|
||||||
|
, local_ptr(_local_ptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
char* operator()(S& s) const
|
||||||
|
{
|
||||||
|
boost::interprocess::managed_shared_memory::size_type shrunk_size = new_size;
|
||||||
|
return s.template allocation_command<char>(boost::interprocess::shrink_in_place, old_size + 128, shrunk_size, local_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t old_size;
|
||||||
|
const size_t new_size;
|
||||||
|
mutable char* local_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SegmentDeallocate : public boost::static_visitor<>
|
||||||
|
{
|
||||||
|
SegmentDeallocate(void* _ptr) : ptr(_ptr) {}
|
||||||
|
|
||||||
|
template<typename S>
|
||||||
|
void operator()(S& s) const { return s.deallocate(ptr); }
|
||||||
|
|
||||||
|
void* ptr;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace shmem
|
} // namespace shmem
|
||||||
} // namespace mq
|
} // namespace mq
|
||||||
} // namespace fair
|
} // namespace fair
|
||||||
|
|
|
@ -27,12 +27,10 @@
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/interprocess/indexes/null_index.hpp>
|
|
||||||
#include <boost/interprocess/ipc/message_queue.hpp>
|
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||||
#include <boost/interprocess/managed_shared_memory.hpp>
|
#include <boost/interprocess/managed_shared_memory.hpp>
|
||||||
#include <boost/interprocess/sync/named_condition.hpp>
|
#include <boost/interprocess/sync/named_condition.hpp>
|
||||||
#include <boost/interprocess/sync/named_mutex.hpp>
|
#include <boost/interprocess/sync/named_mutex.hpp>
|
||||||
#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
|
|
||||||
#include <boost/process.hpp>
|
#include <boost/process.hpp>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
|
@ -40,6 +38,7 @@
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -56,22 +55,12 @@ namespace mq
|
||||||
namespace shmem
|
namespace shmem
|
||||||
{
|
{
|
||||||
|
|
||||||
struct SharedMemoryError : std::runtime_error { using std::runtime_error::runtime_error; };
|
|
||||||
|
|
||||||
using SimpleSeqFitSegment = boost::interprocess::basic_managed_shared_memory<char,
|
|
||||||
boost::interprocess::simple_seq_fit<boost::interprocess::mutex_family>,
|
|
||||||
boost::interprocess::iset_index>;
|
|
||||||
using RBTreeBestFitSegment = boost::interprocess::basic_managed_shared_memory<char,
|
|
||||||
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>,
|
|
||||||
boost::interprocess::iset_index>;
|
|
||||||
|
|
||||||
class Manager
|
class Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Manager(std::string shmId, std::string deviceId, size_t size, const ProgOptions* config)
|
Manager(std::string shmId, std::string deviceId, size_t size, const ProgOptions* config)
|
||||||
: fShmId(std::move(shmId))
|
: fShmId(std::move(shmId))
|
||||||
, fDeviceId(std::move(deviceId))
|
, fDeviceId(std::move(deviceId))
|
||||||
// , fSegment(boost::interprocess::open_or_create, std::string("fmq_" + fShmId + "_main").c_str(), size)
|
|
||||||
, fSegments()
|
, fSegments()
|
||||||
, fManagementSegment(boost::interprocess::open_or_create, std::string("fmq_" + fShmId + "_mng").c_str(), 6553600)
|
, fManagementSegment(boost::interprocess::open_or_create, std::string("fmq_" + fShmId + "_mng").c_str(), 6553600)
|
||||||
, fShmVoidAlloc(fManagementSegment.get_segment_manager())
|
, fShmVoidAlloc(fManagementSegment.get_segment_manager())
|
||||||
|
@ -79,6 +68,7 @@ class Manager
|
||||||
, fRegionEventsCV(boost::interprocess::open_or_create, std::string("fmq_" + fShmId + "_cv").c_str())
|
, fRegionEventsCV(boost::interprocess::open_or_create, std::string("fmq_" + fShmId + "_cv").c_str())
|
||||||
, fRegionEventsSubscriptionActive(false)
|
, fRegionEventsSubscriptionActive(false)
|
||||||
, fDeviceCounter(nullptr)
|
, fDeviceCounter(nullptr)
|
||||||
|
, fShmSegments(nullptr)
|
||||||
, fShmRegions(nullptr)
|
, fShmRegions(nullptr)
|
||||||
, fInterrupted(false)
|
, fInterrupted(false)
|
||||||
, fMsgCounter(0)
|
, fMsgCounter(0)
|
||||||
|
@ -95,52 +85,94 @@ class Manager
|
||||||
bool mlockSegment = false;
|
bool mlockSegment = false;
|
||||||
bool zeroSegment = false;
|
bool zeroSegment = false;
|
||||||
bool autolaunchMonitor = false;
|
bool autolaunchMonitor = false;
|
||||||
|
std::string allocationAlgorithm("rbtree_best_fit");
|
||||||
if (config) {
|
if (config) {
|
||||||
mlockSegment = config->GetProperty<bool>("shm-mlock-segment", mlockSegment);
|
mlockSegment = config->GetProperty<bool>("shm-mlock-segment", mlockSegment);
|
||||||
zeroSegment = config->GetProperty<bool>("shm-zero-segment", zeroSegment);
|
zeroSegment = config->GetProperty<bool>("shm-zero-segment", zeroSegment);
|
||||||
autolaunchMonitor = config->GetProperty<bool>("shm-monitor", autolaunchMonitor);
|
autolaunchMonitor = config->GetProperty<bool>("shm-monitor", autolaunchMonitor);
|
||||||
fThrowOnBadAlloc = config->GetProperty<bool>("shm-throw-bad-alloc", fThrowOnBadAlloc);
|
fThrowOnBadAlloc = config->GetProperty<bool>("shm-throw-bad-alloc", fThrowOnBadAlloc);
|
||||||
|
allocationAlgorithm = config->GetProperty<std::string>("shm-allocation", allocationAlgorithm);
|
||||||
} else {
|
} else {
|
||||||
LOG(debug) << "ProgOptions not available! Using defaults.";
|
LOG(debug) << "ProgOptions not available! Using defaults.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allocationAlgorithm != "rbtree_best_fit" && allocationAlgorithm != "simple_seq_fit") {
|
||||||
|
LOG(error) << "Provided shared memory allocation algorithm '" << allocationAlgorithm << "' is not supported. Supported are 'rbtree_best_fit'/'simple_seq_fit'";
|
||||||
|
throw SharedMemoryError(tools::ToString("Provided shared memory allocation algorithm '", allocationAlgorithm, "' is not supported. Supported are 'rbtree_best_fit'/'simple_seq_fit'"));
|
||||||
|
}
|
||||||
|
|
||||||
if (autolaunchMonitor) {
|
if (autolaunchMonitor) {
|
||||||
StartMonitor(fShmId);
|
StartMonitor(fShmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
std::stringstream ss;
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
||||||
|
|
||||||
|
fShmSegments = fManagementSegment.find_or_construct<Uint64SegmentInfoHashMap>(unique_instance)(fShmVoidAlloc);
|
||||||
|
|
||||||
|
const uint64_t id = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fSegments.emplace(0, RBTreeBestFitSegment(open_only, std::string("fmq_" + fShmId + "_main").c_str()));
|
auto it = fShmSegments->find(id);
|
||||||
LOG(debug) << "opened shared memory segment '" << "fmq_" << fShmId << "_main" << "' of " << fSegments.at(0).get_size() << " bytes. Available are " << fSegments.at(0).get_free_memory() << " bytes.";
|
if (it == fShmSegments->end()) {
|
||||||
|
// no segment with given id exists, creating
|
||||||
|
if (allocationAlgorithm == "rbtree_best_fit") {
|
||||||
|
fSegments.emplace(id, RBTreeBestFitSegment(create_only, std::string("fmq_" + fShmId + "_main").c_str(), size));
|
||||||
|
fShmSegments->emplace(id, AllocationAlgorithm::rbtree_best_fit);
|
||||||
|
} else if (allocationAlgorithm == "simple_seq_fit") {
|
||||||
|
fSegments.emplace(id, SimpleSeqFitSegment(create_only, std::string("fmq_" + fShmId + "_main").c_str(), size));
|
||||||
|
fShmSegments->emplace(id, AllocationAlgorithm::simple_seq_fit);
|
||||||
|
}
|
||||||
|
ss << "Created ";
|
||||||
|
} else {
|
||||||
|
// found segment with the given id, opening
|
||||||
|
if (it->second.fAllocationAlgorithm == AllocationAlgorithm::rbtree_best_fit) {
|
||||||
|
fSegments.emplace(id, RBTreeBestFitSegment(open_only, std::string("fmq_" + fShmId + "_main").c_str()));
|
||||||
|
if (allocationAlgorithm != "rbtree_best_fit") {
|
||||||
|
LOG(warn) << "Allocation algorithm of the opened segment is rbtree_best_fit, but requested is " << allocationAlgorithm << ". Ignoring requested setting.";
|
||||||
|
allocationAlgorithm = "rbtree_best_fit";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fSegments.emplace(id, SimpleSeqFitSegment(open_only, std::string("fmq_" + fShmId + "_main").c_str()));
|
||||||
|
if (allocationAlgorithm != "simple_seq_fit") {
|
||||||
|
LOG(warn) << "Allocation algorithm of the opened segment is simple_seq_fit, but requested is " << allocationAlgorithm << ". Ignoring requested setting.";
|
||||||
|
allocationAlgorithm = "simple_seq_fit";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss << "Opened ";
|
||||||
|
}
|
||||||
|
ss << "shared memory segment '" << "fmq_" << fShmId << "_main_" << id << "'."
|
||||||
|
<< " Size: " << boost::apply_visitor(SegmentSize{}, fSegments.at(id)) << " bytes."
|
||||||
|
<< " Available: " << boost::apply_visitor(SegmentFreeMemory{}, fSegments.at(id)) << " bytes."
|
||||||
|
<< " Allocation algorithm: " << allocationAlgorithm;
|
||||||
|
LOG(debug) << ss.str();
|
||||||
} catch(interprocess_exception&) {
|
} catch(interprocess_exception&) {
|
||||||
fSegments.emplace(0, RBTreeBestFitSegment(create_only, std::string("fmq_" + fShmId + "_main").c_str(), size));
|
LOG(error) << "something went wrong";
|
||||||
LOG(debug) << "created shared memory segment '" << "fmq_" << fShmId << "_main" << "' of " << fSegments.at(0).get_size() << " bytes. Available are " << fSegments.at(0).get_free_memory() << " bytes.";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlockSegment) {
|
if (mlockSegment) {
|
||||||
LOG(debug) << "Locking the managed segment memory pages...";
|
LOG(debug) << "Locking the managed segment memory pages...";
|
||||||
if (mlock(fSegments.at(0).get_address(), fSegments.at(0).get_size()) == -1) {
|
if (mlock(boost::apply_visitor(SegmentAddress{}, fSegments.at(0)), boost::apply_visitor(SegmentSize{}, fSegments.at(0))) == -1) {
|
||||||
LOG(error) << "Could not lock the managed segment memory. Code: " << errno << ", reason: " << strerror(errno);
|
LOG(error) << "Could not lock the managed segment memory. Code: " << errno << ", reason: " << strerror(errno);
|
||||||
}
|
}
|
||||||
LOG(debug) << "Successfully locked the managed segment memory pages.";
|
LOG(debug) << "Successfully locked the managed segment memory pages.";
|
||||||
}
|
}
|
||||||
if (zeroSegment) {
|
if (zeroSegment) {
|
||||||
LOG(debug) << "Zeroing the managed segment free memory...";
|
LOG(debug) << "Zeroing the managed segment free memory...";
|
||||||
fSegments.at(0).zero_free_memory();
|
boost::apply_visitor(SegmentMemoryZeroer{}, fSegments.at(0));
|
||||||
LOG(debug) << "Successfully zeroed the managed segment free memory.";
|
LOG(debug) << "Successfully zeroed the managed segment free memory.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
||||||
|
|
||||||
fShmRegions = fManagementSegment.find_or_construct<Uint64RegionInfoHashMap>(unique_instance)(fShmVoidAlloc);
|
fShmRegions = fManagementSegment.find_or_construct<Uint64RegionInfoHashMap>(unique_instance)(fShmVoidAlloc);
|
||||||
|
|
||||||
#ifdef FAIRMQ_DEBUG_MODE
|
#ifdef FAIRMQ_DEBUG_MODE
|
||||||
fMsgDebug = fManagementSegment.find_or_construct<SizetMsgDebugMap>(unique_instance)(fShmVoidAlloc);
|
fMsgDebug = fManagementSegment.find_or_construct<SizetMsgDebugMap>(unique_instance)(fShmVoidAlloc);
|
||||||
#endif
|
#endif
|
||||||
// store info about the managed segment as region with id 0
|
|
||||||
fShmRegions->emplace(0, RegionInfo("", 0, 0, fShmVoidAlloc));
|
|
||||||
|
|
||||||
fDeviceCounter = fManagementSegment.find<DeviceCounter>(unique_instance).first;
|
fDeviceCounter = fManagementSegment.find<DeviceCounter>(unique_instance).first;
|
||||||
|
|
||||||
|
@ -165,6 +197,7 @@ class Manager
|
||||||
LOG(debug) << "initialized message counter with: " << fShmMsgCounter->fCount;
|
LOG(debug) << "initialized message counter with: " << fShmMsgCounter->fCount;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
fHeartbeatThread = std::thread(&Manager::SendHeartbeats, this);
|
fHeartbeatThread = std::thread(&Manager::SendHeartbeats, this);
|
||||||
}
|
}
|
||||||
|
@ -336,10 +369,10 @@ class Manager
|
||||||
|
|
||||||
for (const auto& e : *fShmRegions) {
|
for (const auto& e : *fShmRegions) {
|
||||||
fair::mq::RegionInfo info;
|
fair::mq::RegionInfo info;
|
||||||
|
info.managed = false;
|
||||||
info.id = e.first;
|
info.id = e.first;
|
||||||
info.flags = e.second.fUserFlags;
|
info.flags = e.second.fUserFlags;
|
||||||
info.event = e.second.fDestroyed ? RegionEvent::destroyed : RegionEvent::created;
|
info.event = e.second.fDestroyed ? RegionEvent::destroyed : RegionEvent::created;
|
||||||
if (info.id != 0) {
|
|
||||||
if (!e.second.fDestroyed) {
|
if (!e.second.fDestroyed) {
|
||||||
auto region = GetRegionUnsafe(info.id);
|
auto region = GetRegionUnsafe(info.id);
|
||||||
info.ptr = region->fRegion.get_address();
|
info.ptr = region->fRegion.get_address();
|
||||||
|
@ -349,17 +382,17 @@ class Manager
|
||||||
info.size = 0;
|
info.size = 0;
|
||||||
}
|
}
|
||||||
result.push_back(info);
|
result.push_back(info);
|
||||||
} else {
|
|
||||||
if (!e.second.fDestroyed) {
|
|
||||||
info.ptr = fSegments.at(0).get_address();
|
|
||||||
info.size = fSegments.at(0).get_size();
|
|
||||||
} else {
|
|
||||||
info.ptr = nullptr;
|
|
||||||
info.size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& e : *fShmSegments) {
|
||||||
|
fair::mq::RegionInfo info;
|
||||||
|
info.managed = true;
|
||||||
|
info.id = e.first;
|
||||||
|
info.event = RegionEvent::created;
|
||||||
|
info.ptr = boost::apply_visitor(SegmentAddress{}, fSegments.at(e.first));
|
||||||
|
info.size = boost::apply_visitor(SegmentSize{}, fSegments.at(e.first));
|
||||||
result.push_back(info);
|
result.push_back(info);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -462,8 +495,14 @@ class Manager
|
||||||
|
|
||||||
bool ThrowingOnBadAlloc() const { return fThrowOnBadAlloc; }
|
bool ThrowingOnBadAlloc() const { return fThrowOnBadAlloc; }
|
||||||
|
|
||||||
boost::interprocess::managed_shared_memory::handle_t GetHandleFromAddress(const void* ptr) const { return fSegments.at(0).get_handle_from_address(ptr); }
|
boost::interprocess::managed_shared_memory::handle_t GetHandleFromAddress(const void* ptr) const
|
||||||
void* GetAddressFromHandle(const boost::interprocess::managed_shared_memory::handle_t handle) const { return fSegments.at(0).get_address_from_handle(handle); }
|
{
|
||||||
|
return boost::apply_visitor(SegmentHandleFromAddress{ptr}, fSegments.at(0));
|
||||||
|
}
|
||||||
|
void* GetAddressFromHandle(const boost::interprocess::managed_shared_memory::handle_t handle) const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(SegmentAddressFromHandle{handle}, fSegments.at(0));
|
||||||
|
}
|
||||||
|
|
||||||
char* Allocate(const size_t size, size_t alignment = 0)
|
char* Allocate(const size_t size, size_t alignment = 0)
|
||||||
{
|
{
|
||||||
|
@ -475,19 +514,19 @@ class Manager
|
||||||
// boost::interprocess::managed_shared_memory::size_type actualSize = size;
|
// boost::interprocess::managed_shared_memory::size_type actualSize = size;
|
||||||
// char* hint = 0; // unused for boost::interprocess::allocate_new
|
// char* hint = 0; // unused for boost::interprocess::allocate_new
|
||||||
// ptr = fSegments.at(0).allocation_command<char>(boost::interprocess::allocate_new, size, actualSize, hint);
|
// ptr = fSegments.at(0).allocation_command<char>(boost::interprocess::allocate_new, size, actualSize, hint);
|
||||||
size_t segmentSize = fSegments.at(0).get_size();
|
size_t segmentSize = boost::apply_visitor(SegmentSize{}, fSegments.at(0));
|
||||||
if (size > segmentSize) {
|
if (size > segmentSize) {
|
||||||
throw MessageBadAlloc(tools::ToString("Requested message size (", size, ") exceeds segment size (", segmentSize, ")"));
|
throw MessageBadAlloc(tools::ToString("Requested message size (", size, ") exceeds segment size (", segmentSize, ")"));
|
||||||
}
|
}
|
||||||
if (alignment == 0) {
|
if (alignment == 0) {
|
||||||
ptr = reinterpret_cast<char*>(fSegments.at(0).allocate(size));
|
ptr = reinterpret_cast<char*>(boost::apply_visitor(SegmentAllocate{size}, fSegments.at(0)));
|
||||||
} else {
|
} else {
|
||||||
ptr = reinterpret_cast<char*>(fSegments.at(0).allocate_aligned(size, alignment));
|
ptr = reinterpret_cast<char*>(boost::apply_visitor(SegmentAllocateAligned{size, alignment}, fSegments.at(0)));
|
||||||
}
|
}
|
||||||
} catch (boost::interprocess::bad_alloc& ba) {
|
} catch (boost::interprocess::bad_alloc& ba) {
|
||||||
// LOG(warn) << "Shared memory full...";
|
// LOG(warn) << "Shared memory full...";
|
||||||
if (ThrowingOnBadAlloc()) {
|
if (ThrowingOnBadAlloc()) {
|
||||||
throw MessageBadAlloc(tools::ToString("shmem: could not create a message of size ", size, ", alignment: ", (alignment != 0) ? std::to_string(alignment) : "default", ", free memory: ", fSegments.at(0).get_free_memory()));
|
throw MessageBadAlloc(tools::ToString("shmem: could not create a message of size ", size, ", alignment: ", (alignment != 0) ? std::to_string(alignment) : "default", ", free memory: ", boost::apply_visitor(SegmentFreeMemory{}, fSegments.at(0))));
|
||||||
}
|
}
|
||||||
// rateLimiter.maybe_sleep();
|
// rateLimiter.maybe_sleep();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
@ -509,7 +548,7 @@ class Manager
|
||||||
|
|
||||||
void Deallocate(boost::interprocess::managed_shared_memory::handle_t handle)
|
void Deallocate(boost::interprocess::managed_shared_memory::handle_t handle)
|
||||||
{
|
{
|
||||||
fSegments.at(0).deallocate(GetAddressFromHandle(handle));
|
boost::apply_visitor(SegmentDeallocate{GetAddressFromHandle(handle)}, fSegments.at(0));
|
||||||
#ifdef FAIRMQ_DEBUG_MODE
|
#ifdef FAIRMQ_DEBUG_MODE
|
||||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(fShmMtx);
|
||||||
DecrementShmMsgCounter();
|
DecrementShmMsgCounter();
|
||||||
|
@ -519,9 +558,7 @@ class Manager
|
||||||
|
|
||||||
char* ShrinkInPlace(size_t oldSize, size_t newSize, char* localPtr)
|
char* ShrinkInPlace(size_t oldSize, size_t newSize, char* localPtr)
|
||||||
{
|
{
|
||||||
using namespace boost::interprocess;
|
return boost::apply_visitor(SegmentBufferShrink{oldSize, newSize, localPtr}, fSegments.at(0));
|
||||||
managed_shared_memory::size_type shrunkSize = newSize;
|
|
||||||
return fSegments.at(0).allocation_command<char>(shrink_in_place, oldSize + 128, shrunkSize, localPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Manager()
|
~Manager()
|
||||||
|
@ -563,8 +600,7 @@ class Manager
|
||||||
private:
|
private:
|
||||||
std::string fShmId;
|
std::string fShmId;
|
||||||
std::string fDeviceId;
|
std::string fDeviceId;
|
||||||
// boost::interprocess::managed_shared_memory fSegment;
|
std::unordered_map<uint64_t, boost::variant<RBTreeBestFitSegment, SimpleSeqFitSegment>> fSegments;
|
||||||
std::unordered_map<uint64_t, RBTreeBestFitSegment> fSegments;
|
|
||||||
boost::interprocess::managed_shared_memory fManagementSegment;
|
boost::interprocess::managed_shared_memory fManagementSegment;
|
||||||
VoidAlloc fShmVoidAlloc;
|
VoidAlloc fShmVoidAlloc;
|
||||||
boost::interprocess::named_mutex fShmMtx;
|
boost::interprocess::named_mutex fShmMtx;
|
||||||
|
@ -576,6 +612,7 @@ class Manager
|
||||||
std::unordered_map<uint64_t, RegionEvent> fObservedRegionEvents;
|
std::unordered_map<uint64_t, RegionEvent> fObservedRegionEvents;
|
||||||
|
|
||||||
DeviceCounter* fDeviceCounter;
|
DeviceCounter* fDeviceCounter;
|
||||||
|
Uint64SegmentInfoHashMap* fShmSegments;
|
||||||
Uint64RegionInfoHashMap* fShmRegions;
|
Uint64RegionInfoHashMap* fShmRegions;
|
||||||
std::unordered_map<uint64_t, std::unique_ptr<Region>> fRegions;
|
std::unordered_map<uint64_t, std::unique_ptr<Region>> fRegions;
|
||||||
|
|
||||||
|
|
|
@ -205,10 +205,6 @@ void Monitor::Interactive()
|
||||||
cout << "\n[q] --> quitting." << endl;
|
cout << "\n[q] --> quitting." << endl;
|
||||||
fTerminating = true;
|
fTerminating = true;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
|
||||||
cout << "\n[p] --> active queues:" << endl;
|
|
||||||
PrintQueues();
|
|
||||||
break;
|
|
||||||
case 'x':
|
case 'x':
|
||||||
cout << "\n[x] --> closing shared memory:" << endl;
|
cout << "\n[x] --> closing shared memory:" << endl;
|
||||||
if (!fViewOnly) {
|
if (!fViewOnly) {
|
||||||
|
@ -254,6 +250,7 @@ void Monitor::Interactive()
|
||||||
|
|
||||||
void Monitor::CheckSegment()
|
void Monitor::CheckSegment()
|
||||||
{
|
{
|
||||||
|
using namespace boost::interprocess;
|
||||||
char c = '#';
|
char c = '#';
|
||||||
|
|
||||||
if (fInteractive) {
|
if (fInteractive) {
|
||||||
|
@ -281,8 +278,27 @@ void Monitor::CheckSegment()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bipc::managed_shared_memory segment(bipc::open_only, fSegmentName.c_str());
|
managed_shared_memory managementSegment(open_only, fManagementSegmentName.c_str());
|
||||||
bipc::managed_shared_memory managementSegment(bipc::open_only, fManagementSegmentName.c_str());
|
|
||||||
|
Uint64SegmentInfoHashMap* segmentInfos = managementSegment.find<Uint64SegmentInfoHashMap>(unique_instance).first;
|
||||||
|
std::unordered_map<uint64_t, boost::variant<RBTreeBestFitSegment, SimpleSeqFitSegment>> segments;
|
||||||
|
|
||||||
|
if (!segmentInfos) {
|
||||||
|
cout << "Found management segment, but cannot locate segment info, something went wrong..." << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t id = 0;
|
||||||
|
|
||||||
|
auto it = segmentInfos->find(id);
|
||||||
|
if (it != segmentInfos->end()) {
|
||||||
|
// found segment with the given id, opening
|
||||||
|
if (it->second.fAllocationAlgorithm == AllocationAlgorithm::rbtree_best_fit) {
|
||||||
|
segments.emplace(id, RBTreeBestFitSegment(open_only, fSegmentName.c_str()));
|
||||||
|
} else {
|
||||||
|
segments.emplace(id, SimpleSeqFitSegment(open_only, fSegmentName.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fSeenOnce = true;
|
fSeenOnce = true;
|
||||||
|
|
||||||
|
@ -292,12 +308,12 @@ void Monitor::CheckSegment()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fInteractive || fViewOnly) {
|
if (fInteractive || fViewOnly) {
|
||||||
DeviceCounter* dc = managementSegment.find<DeviceCounter>(bipc::unique_instance).first;
|
DeviceCounter* dc = managementSegment.find<DeviceCounter>(unique_instance).first;
|
||||||
if (dc) {
|
if (dc) {
|
||||||
numDevices = dc->fCount;
|
numDevices = dc->fCount;
|
||||||
}
|
}
|
||||||
#ifdef FAIRMQ_DEBUG_MODE
|
#ifdef FAIRMQ_DEBUG_MODE
|
||||||
MsgCounter* mc = managementSegment.find<MsgCounter>(bipc::unique_instance).first;
|
MsgCounter* mc = managementSegment.find<MsgCounter>(unique_instance).first;
|
||||||
if (mc) {
|
if (mc) {
|
||||||
numMessages = mc->fCount;
|
numMessages = mc->fCount;
|
||||||
}
|
}
|
||||||
|
@ -320,8 +336,8 @@ void Monitor::CheckSegment()
|
||||||
if (fInteractive) {
|
if (fInteractive) {
|
||||||
cout << "| "
|
cout << "| "
|
||||||
<< setw(18) << fSegmentName << " | "
|
<< setw(18) << fSegmentName << " | "
|
||||||
<< setw(10) << segment.get_size() << " | "
|
<< setw(10) << boost::apply_visitor(SegmentSize{}, segments.at(id)) << " | "
|
||||||
<< setw(10) << segment.get_free_memory() << " | "
|
<< setw(10) << boost::apply_visitor(SegmentFreeMemory{}, segments.at(id)) << " | "
|
||||||
<< setw(8) << numDevices << " | "
|
<< setw(8) << numDevices << " | "
|
||||||
#ifdef FAIRMQ_DEBUG_MODE
|
#ifdef FAIRMQ_DEBUG_MODE
|
||||||
<< setw(8) << numMessages << " | "
|
<< setw(8) << numMessages << " | "
|
||||||
|
@ -331,8 +347,8 @@ void Monitor::CheckSegment()
|
||||||
<< setw(10) << (fViewOnly ? "view only" : to_string(duration)) << " |"
|
<< setw(10) << (fViewOnly ? "view only" : to_string(duration)) << " |"
|
||||||
<< c << flush;
|
<< c << flush;
|
||||||
} else if (fViewOnly) {
|
} else if (fViewOnly) {
|
||||||
size_t free = segment.get_free_memory();
|
size_t free = boost::apply_visitor(SegmentFreeMemory{}, segments.at(id));
|
||||||
size_t total = segment.get_size();
|
size_t total = boost::apply_visitor(SegmentSize{}, segments.at(id));
|
||||||
size_t used = total - free;
|
size_t used = total - free;
|
||||||
// size_t mfree = managementSegment.get_free_memory();
|
// size_t mfree = managementSegment.get_free_memory();
|
||||||
// size_t mtotal = managementSegment.get_size();
|
// size_t mtotal = managementSegment.get_size();
|
||||||
|
@ -459,44 +475,6 @@ vector<BufferDebugInfo> Monitor::GetDebugInfo(const SessionId& sessionId)
|
||||||
return GetDebugInfo(shmId);
|
return GetDebugInfo(shmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Monitor::PrintQueues()
|
|
||||||
{
|
|
||||||
cout << '\n';
|
|
||||||
|
|
||||||
try {
|
|
||||||
bipc::managed_shared_memory segment(bipc::open_only, fSegmentName.c_str());
|
|
||||||
StrVector* queues = segment.find<StrVector>(string("fmq_" + fShmId + "_qs").c_str()).first;
|
|
||||||
if (queues) {
|
|
||||||
cout << "found " << queues->size() << " queue(s):" << endl;
|
|
||||||
|
|
||||||
for (const auto& queue : *queues) {
|
|
||||||
string name(queue.c_str());
|
|
||||||
cout << '\t' << name << " : ";
|
|
||||||
atomic<int>* queueSize = segment.find<atomic<int>>(name.c_str()).first;
|
|
||||||
if (queueSize) {
|
|
||||||
cout << *queueSize << " messages" << endl;
|
|
||||||
} else {
|
|
||||||
cout << "\tqueue does not have a queue size entry." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cout << "\tno queues found" << endl;
|
|
||||||
}
|
|
||||||
} catch (bie&) {
|
|
||||||
cout << "\tno queues found" << endl;
|
|
||||||
} catch (out_of_range&) {
|
|
||||||
cout << "\tno queues found" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "\n --> last heartbeats: " << endl << endl;
|
|
||||||
auto now = chrono::high_resolution_clock::now();
|
|
||||||
for (const auto& h : fDeviceHeartbeats) {
|
|
||||||
cout << "\t" << h.first << " : " << chrono::duration<double, milli>(now - h.second).count() << "ms ago." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Monitor::PrintHeader()
|
void Monitor::PrintHeader()
|
||||||
{
|
{
|
||||||
cout << "| "
|
cout << "| "
|
||||||
|
@ -512,7 +490,6 @@ void Monitor::PrintHeader()
|
||||||
void Monitor::PrintHelp()
|
void Monitor::PrintHelp()
|
||||||
{
|
{
|
||||||
cout << "controls: [x] close memory, "
|
cout << "controls: [x] close memory, "
|
||||||
<< "[p] print queues, "
|
|
||||||
<< "[b] print a list of allocated messages (only available when compiled with FAIMQ_DEBUG_MODE=ON), "
|
<< "[b] print a list of allocated messages (only available when compiled with FAIMQ_DEBUG_MODE=ON), "
|
||||||
<< "[h] help, "
|
<< "[h] help, "
|
||||||
<< "[q] quit." << endl;
|
<< "[q] quit." << endl;
|
||||||
|
|
|
@ -92,7 +92,6 @@ class Monitor
|
||||||
private:
|
private:
|
||||||
void PrintHeader();
|
void PrintHeader();
|
||||||
void PrintHelp();
|
void PrintHelp();
|
||||||
void PrintQueues();
|
|
||||||
void MonitorHeartbeats();
|
void MonitorHeartbeats();
|
||||||
void CheckSegment();
|
void CheckSegment();
|
||||||
void Interactive();
|
void Interactive();
|
||||||
|
|
|
@ -56,7 +56,7 @@ class Context
|
||||||
throw ContextError(tools::ToString("failed configuring context, reason: ", zmq_strerror(errno)));
|
throw ContextError(tools::ToString("failed configuring context, reason: ", zmq_strerror(errno)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fRegionEvents.emplace(0, nullptr, 0, 0, RegionEvent::local_only);
|
fRegionEvents.emplace(true, 0, nullptr, 0, 0, RegionEvent::local_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context(const Context&) = delete;
|
Context(const Context&) = delete;
|
||||||
|
@ -120,13 +120,13 @@ class Context
|
||||||
return fRegionCounter;
|
return fRegionCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddRegion(uint64_t id, void* ptr, size_t size, int64_t userFlags, RegionEvent event)
|
void AddRegion(bool managed, uint64_t id, void* ptr, size_t size, int64_t userFlags, RegionEvent event)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(fMtx);
|
std::lock_guard<std::mutex> lock(fMtx);
|
||||||
++fRegionCounter;
|
++fRegionCounter;
|
||||||
fRegionInfos.emplace_back(id, ptr, size, userFlags, event);
|
fRegionInfos.emplace_back(managed, id, ptr, size, userFlags, event);
|
||||||
fRegionEvents.emplace(id, ptr, size, userFlags, event);
|
fRegionEvents.emplace(managed, id, ptr, size, userFlags, event);
|
||||||
}
|
}
|
||||||
fRegionEventsCV.notify_one();
|
fRegionEventsCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ class TransportFactory final : public FairMQTransportFactory
|
||||||
{
|
{
|
||||||
UnmanagedRegionPtr ptr = tools::make_unique<UnmanagedRegion>(*fCtx, size, userFlags, callback, bulkCallback, this);
|
UnmanagedRegionPtr ptr = tools::make_unique<UnmanagedRegion>(*fCtx, size, userFlags, callback, bulkCallback, this);
|
||||||
auto zPtr = static_cast<UnmanagedRegion*>(ptr.get());
|
auto zPtr = static_cast<UnmanagedRegion*>(ptr.get());
|
||||||
fCtx->AddRegion(zPtr->GetId(), zPtr->GetData(), zPtr->GetSize(), zPtr->GetUserFlags(), RegionEvent::created);
|
fCtx->AddRegion(false, zPtr->GetId(), zPtr->GetData(), zPtr->GetSize(), zPtr->GetUserFlags(), RegionEvent::created);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ void RegionEventSubscriptions(const string& transport)
|
||||||
ASSERT_EQ(factory->SubscribedToRegionEvents(), false);
|
ASSERT_EQ(factory->SubscribedToRegionEvents(), false);
|
||||||
factory->SubscribeToRegionEvents([&](FairMQRegionInfo info) {
|
factory->SubscribeToRegionEvents([&](FairMQRegionInfo info) {
|
||||||
LOG(warn) << ">>>" << info.event;
|
LOG(warn) << ">>>" << info.event;
|
||||||
|
LOG(warn) << "managed: " << info.managed;
|
||||||
LOG(warn) << "id: " << info.id;
|
LOG(warn) << "id: " << info.id;
|
||||||
LOG(warn) << "ptr: " << info.ptr;
|
LOG(warn) << "ptr: " << info.ptr;
|
||||||
LOG(warn) << "size: " << info.size;
|
LOG(warn) << "size: " << info.size;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user