TMapFile This class implements a shared memory region mapped to a file. Objects can be placed into this shared memory area using the Add() member function. To actually place a copy of the object is shared memory call Update() also whenever the mapped object(s) change(s) call Update() to put a fresh copy in the shared memory. This extra step is necessary since it is not possible to share objects with virtual pointers between processes (the vtbl ptr points to the originators unique address space and can not be used by the consumer process(es)). Consumer processes can map the memory region from this file and access the objects stored in it via the Get() method (which returns a copy of the object stored in the shared memory with correct vtbl ptr set). Only objects of classes with a Streamer() member function defined can be shared. I know the current implementation is not ideal (you need to copy to and from the shared memory file) but the main problem is with the class' virtual_table pointer. This pointer points to a table unique for every process. Therefore, different options are: 1) One could allocate an object directly in shared memory in the producer, but the consumer still has to copy the object from shared memory into a local object which has the correct vtbl pointer for that process (copy ctor's can be used for creating the local copy). 2) Another possibility is to only allow objects without virtual functions in shared memory (like simple C structs), or to forbid (how?) the consumer from calling any virtual functions of the objects in shared memory. 3) A last option is to copy the object internals to shared memory and copy them again from there. This is what is done in the TMapFile (using the object Streamer() to make a deep copy). Option 1) saves one copy, but requires solid copy ctor's (along the full inheritance chain) to rebuild the object in the consumer. Most classes don't provide these copy ctor's, especially not when objects contain collections, etc. 2) is too limiting or dangerous (calling accidentally a virtual function will segv). So since we have a robust Streamer mechanism I opted for 3).
virtual | ~TMapFile() |
void | TObject::AbstractMethod(const char* method) const |
void | Add(const TObject* obj, const char* name = "") |
virtual void | TObject::AppendPad(Option_t* option = "") |
virtual void | Browse(TBrowser* b) |
Bool_t | cd(const char* path = 0) |
static TClass* | Class() |
virtual const char* | TObject::ClassName() const |
virtual void | TObject::Clear(Option_t* = "") |
virtual TObject* | TObject::Clone(const char* newname = "") const |
void | Close(Option_t* option = "") |
virtual Int_t | TObject::Compare(const TObject* obj) const |
virtual void | TObject::Copy(TObject& object) const |
static TMapFile* | Create(const char* name, Option_t* option = "READ", Int_t size = kDefaultMapSize, const char* title = "") |
virtual void | TObject::Delete(Option_t* option = "")MENU |
virtual Int_t | TObject::DistancetoPrimitive(Int_t px, Int_t py) |
virtual void | TObject::Draw(Option_t* option = "") |
virtual void | TObject::DrawClass() constMENU |
virtual TObject* | TObject::DrawClone(Option_t* option = "") constMENU |
virtual void | TObject::Dump() constMENU |
virtual void | TObject::Error(const char* method, const char* msgfmt) const |
virtual void | TObject::Execute(const char* method, const char* params, Int_t* error = 0) |
virtual void | TObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0) |
virtual void | TObject::ExecuteEvent(Int_t event, Int_t px, Int_t py) |
virtual void | TObject::Fatal(const char* method, const char* msgfmt) const |
virtual TObject* | TObject::FindObject(const char* name) const |
virtual TObject* | TObject::FindObject(const TObject* obj) const |
TObject* | Get(const char* name, TObject* retObj = 0) |
void* | GetBaseAddr() const |
void* | GetBreakval() const |
TDirectory* | GetDirectory() const |
virtual Option_t* | TObject::GetDrawOption() const |
static Long_t | TObject::GetDtorOnly() |
Int_t | GetFd() const |
TMapRec* | GetFirst() const |
virtual const char* | TObject::GetIconName() const |
TMapRec* | GetLast() const |
void* | GetMmallocDesc() const |
virtual const char* | GetName() const |
virtual char* | TObject::GetObjectInfo(Int_t px, Int_t py) const |
static Bool_t | TObject::GetObjectStat() |
virtual const char* | GetOption() const |
Int_t | GetSize() const |
virtual const char* | GetTitle() const |
virtual UInt_t | TObject::GetUniqueID() const |
virtual Bool_t | TObject::HandleTimer(TTimer* timer) |
virtual ULong_t | TObject::Hash() const |
virtual void | TObject::Info(const char* method, const char* msgfmt) const |
virtual Bool_t | TObject::InheritsFrom(const char* classname) const |
virtual Bool_t | TObject::InheritsFrom(const TClass* cl) const |
virtual void | TObject::Inspect() constMENU |
void | TObject::InvertBit(UInt_t f) |
virtual TClass* | IsA() const |
virtual Bool_t | TObject::IsEqual(const TObject* obj) const |
virtual Bool_t | IsFolder() const |
Bool_t | TObject::IsOnHeap() const |
virtual Bool_t | TObject::IsSortable() const |
Bool_t | IsWritable() const |
Bool_t | TObject::IsZombie() const |
virtual void | ls(Option_t* option = "") const |
void | TObject::MayNotUse(const char* method) const |
virtual Bool_t | TObject::Notify() |
static void | operator delete(void* vp) |
static void | TObject::operator delete[](void* ptr) |
static void | TObject::operator delete[](void* ptr, void* vp) |
void* | TObject::operator new(size_t sz) |
void* | TObject::operator new(size_t sz, void* vp) |
void* | TObject::operator new[](size_t sz) |
void* | TObject::operator new[](size_t sz, void* vp) |
void* | OrgAddress(void* addr) const |
virtual void | TObject::Paint(Option_t* option = "") |
virtual void | TObject::Pop() |
virtual void | Print(Option_t* option = "") const |
virtual Int_t | TObject::Read(const char* name) |
virtual void | TObject::RecursiveRemove(TObject* obj) |
TObject* | Remove(TObject* obj) |
TObject* | Remove(const char* name) |
void | RemoveAll() |
void | TObject::ResetBit(UInt_t f) |
virtual void | TObject::SaveAs(const char* filename = "", Option_t* option = "") constMENU |
virtual void | TObject::SavePrimitive(basic_ostream<char,char_traits<char> >& out, Option_t* option = "") |
void | TObject::SetBit(UInt_t f) |
void | TObject::SetBit(UInt_t f, Bool_t set) |
virtual void | TObject::SetDrawOption(Option_t* option = "")MENU |
static void | TObject::SetDtorOnly(void* obj) |
static void | SetMapAddress(Long_t addr) |
static void | TObject::SetObjectStat(Bool_t stat) |
virtual void | TObject::SetUniqueID(UInt_t uid) |
virtual void | ShowMembers(TMemberInspector& insp, char* parent) |
virtual void | Streamer(TBuffer& b) |
void | StreamerNVirtual(TBuffer& b) |
virtual void | TObject::SysError(const char* method, const char* msgfmt) const |
Bool_t | TObject::TestBit(UInt_t f) const |
Int_t | TObject::TestBits(UInt_t f) const |
void | Update(TObject* obj = 0) |
virtual void | TObject::UseCurrentStyle() |
virtual void | TObject::Warning(const char* method, const char* msgfmt) const |
static TMapFile* | WhichMapFile(void* addr) |
virtual Int_t | TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) |
virtual Int_t | TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const |
TMapFile() | |
TMapFile(const TMapFile& f, Long_t offset = 0) | |
TMapFile(const char* name, const char* title, Option_t* option, Int_t size, TMapFile*& newMapFile) | |
Int_t | AcquireSemaphore() |
void | CreateSemaphore(Int_t pid = 0) |
void | DeleteSemaphore() |
virtual void | TObject::DoError(int level, const char* location, const char* fmt, va_list va) const |
TMapFile* | FindShadowMapFile() |
Int_t | GetBestBuffer() |
void | InitDirectory() |
void | TObject::MakeZombie() |
static void* | MapToAddress() |
void | operator=(const TMapFile& rhs) |
Int_t | ReleaseSemaphore() |
TObject* | Remove(TObject* obj, Bool_t lock) |
TObject* | Remove(const char* name, Bool_t lock) |
void | SumBuffer(Int_t bufsize) |
enum { | kDefaultMapSize | |
}; | ||
enum TObject::EStatusBits { | kCanDelete | |
kMustCleanup | ||
kObjInCanvas | ||
kIsReferenced | ||
kHasUUID | ||
kCannotPick | ||
kNoContextMenu | ||
kInvalidObject | ||
}; | ||
enum TObject::[unnamed] { | kIsOnHeap | |
kNotDeleted | ||
kZombie | ||
kBitMask | ||
kSingleKey | ||
kOverwrite | ||
kWriteDelete | ||
}; |
ULong_t | fBaseAddr | Base address of mapped memory region |
TList* | fBrowseList | List of KeyMapFile objects |
TDirectory* | fDirectory | Pointer to directory associated to this mapfile |
Int_t | fFd | Descriptor of mapped file |
TMapRec* | fFirst | List of streamed objects is shared memory |
TObject* | fGetting | Don't deadlock in update mode, when from Get() Add() is called |
TMapRec* | fLast | Last object in list of shared objects |
void* | fMmallocDesc | Pointer to mmalloc descriptor |
char* | fName | Name of mapped file |
Long_t | fOffset | Offset in bytes for region mapped by reader |
char* | fOption | Directory creation options |
Int_t | fSemaphore | Modification semaphore (or getpid() for WIN32) |
Int_t | fSize | Original start size of memory mapped region |
Double_t | fSum2Buffer | Sum of squares of buffer sizes of objects written so far |
Double_t | fSumBuffer | Sum of buffer sizes of objects written sofar |
char* | fTitle | Title of mapped file |
Int_t | fVersion | ROOT version (or -1 for shadow map file) |
Bool_t | fWritable | TRUE if mapped file opened in RDWR mode |
Int_t | fWritten | Number of objects written sofar |
static Long_t | fgMapAddress | Map to this address, set address via SetMapAddress() |
static void* | fgMmallocDesc | Used in Close() and operator delete() |
ULong_t | fhSemaphore | HANDLE of WIN32 Mutex object to implement semaphore |
Create a memory mapped file. This opens a file (to which the memory will be mapped) and attaches a memory region to it. Option can be either: "NEW", "CREATE", "RECREATE", "UPDATE" or "READ" (see TFile). The default open mode is "READ". The size argument specifies the maximum size of shared memory file in bytes. This protected ctor is called via the static Create() method.
Private copy ctor. Used by the the ctor to create a new version of TMapFile in the memory mapped heap. It's main purpose is to correctly create the string data members.
Remove object from shared memory. Returns pointer to removed object if successful, 0 otherwise.
Remove object by name from shared memory. Returns pointer to removed object if successful, 0 otherwise.
Return pointer to object retrieved from shared memory. The object must be deleted after use. If delObj is a pointer to a previously allocated object it will be deleted. Returns 0 in case object with the given name does not exist.
Create semaphore used for synchronizing access to shared memory.
Return the best buffer size for objects in this file. The best buffer size is estimated based on the current mean value and standard deviation of all objects written so far to this file. Returns mean value + one standard deviation.
Create a memory mapped file. This opens a file (to which the memory will be mapped) and attaches a memory region to it. Option can be either: "NEW", "CREATE", "RECREATE", "UPDATE" or "READ" (see TFile). The default open mode is "READ". The size argument specifies the maximum size of shared memory file in bytes. TMapFile's can only be created via this method. Create() enforces that a TMapFile is always on the memory mapped heap (when "NEW", "CREATE" or "RECREATE" are used).
Set preferred map address. Find out preferred map address as follows: 1) Run consumer program to find the preferred map address: $ root root [0] m = TMapFile::Create("dummy.map", "recreate", 10000000); root [1] m.Print() Memory mapped file: dummy.map Title: Option: CREATE Mapped Memory region: 0x40b4c000 - 0x40d95f00 (2.29 MB) Current breakval: 0x40b53000 root [2] .q $ rm dummy.map Remember begin of mapped region, i.e. 0x40b4c000 2) Add to producer program, just before creating the TMapFile: TMapFile::SetMapAddress(0x40b4c000); Repeat this if more than one map file is being used. The above procedure allow programs using, e.g., different number of shared libraries (that cause the default mapping address to be different) to create shared memory regions in the same location without overwriting a shared library. The above assumes the consumer program is larger (i.e. has more shared memory occupied) than the producer. If this is not true inverse the procedure.
Return the base address at which we would like the next TMapFile's mapped data to start. For now, we let the system decide (start address 0). There are a lot of issues to deal with here to make this work reasonably, including: - Avoid memory collisions with existing mapped address spaces - Reclaim address spaces when their mmalloc heaps are unmapped - When mmalloc heaps are shared between processes they have to be mapped at the same addresses in each Once created, a mmalloc heap that is to be mapped back in must be mapped at the original address. I.E. each TMapFile will expect to be remapped at it's original address. This becomes a problem if the desired address is already in use.
Need special "operator delete" in which we close the shared memory.
This has to be done after the dtor chain has been finished.