RegionRegistry.h
Go to the documentation of this file.00001 
00002 #ifndef INCLUDED_RegionRegistry_h_
00003 #define INCLUDED_RegionRegistry_h_
00004 
00005 #ifdef PLATFORM_APERIOS
00006 #  warning RegionRegistry is not Aperios compatable
00007 #else
00008 
00009 #include "ListMemBuf.h"
00010 #include "RCRegion.h"
00011 #include "Shared/MarkScope.h"
00012 #include "ProcessID.h"
00013 
00014 
00015 template<unsigned int MAX_REGIONS, unsigned int NAME_LEN>
00016 class RegionRegistry {
00017 protected:
00018 
00019   mutable MutexLock<ProcessID::NumProcesses> lock;
00020   
00021 
00022   struct entry {
00023 
00024     entry() : id() { name[0]='\0'; }
00025 
00026     entry(const char n[], RCRegion* r) : id(r->ID()) {
00027       strncpy(name,n,NAME_LEN);
00028       name[NAME_LEN]='\0';
00029     }
00030     char name[NAME_LEN+1]; 
00031     RCRegion::Identifier id; 
00032   };
00033   typedef ListMemBuf<entry,MAX_REGIONS> registry_t;  
00034   registry_t avail; 
00035 
00036 public:
00037   static const unsigned int CAPACITY=MAX_REGIONS; 
00038   static const unsigned int REGION_NAME_LEN=NAME_LEN; 
00039   typedef typename registry_t::index_t index_t; 
00040 
00041 
00042   RegionRegistry() : lock(), avail() {}
00043   
00044 
00045   ~RegionRegistry() {
00046     MarkScope autolock(lock);
00047     avail.clear();
00048   }
00049   
00050 
00051   index_t findRegion(const std::string& name) const {
00052     MarkScope autolock(lock);
00053     if(name.size()>NAME_LEN)
00054       std::cerr << "WARNING: RegionRegistry::attach("<<name<<") is too long, max is " << NAME_LEN << std::endl;
00055     for(index_t it=begin(); it!=end(); it=next(it))
00056       if(name==avail[it].name)
00057         return it;
00058     return avail.end();
00059   }
00060 
00061 
00062 
00063   index_t registerRegion(const std::string& name, const RCRegion * region) {
00064     MarkScope autolock(lock,ProcessID::getID());
00065     index_t it=findRegion(name);
00066     if(it!=end()) { 
00067       if(avail[it].regions[ProcessID::getID()]==region)
00068         return it; 
00069       return end(); 
00070     }
00071     
00072     return avail.push_back(entry(name.c_str(),region));
00073   }
00074   
00075 
00076 
00077   RCRegion * registerRegion(const std::string& name, size_t size) {
00078     MarkScope autolock(lock);
00079     index_t it=findRegion(name);
00080     if(it!=end()) {
00081       
00082       return RCRegion::attach(avail[it].id);
00083     } else {
00084       
00085       RCRegion * region = new RCRegion(name,size);
00086       avail.push_back(entry(name.c_str(),region));
00087       return region;
00088     }
00089   }
00090   
00091 
00092   RCRegion * operator[](index_t it) const {
00093     MarkScope autolock(lock,ProcessID::getID());
00094     if(it==end())
00095       return NULL;
00096     return RCRegion::attach(avail[it].id);
00097   }
00098   
00099 
00100   void erase(index_t it) {
00101     MarkScope autolock(lock,ProcessID::getID());
00102     avail.erase(it);
00103   }
00104   
00105   index_t begin() const { return avail.begin(); } 
00106   index_t next(index_t it) const { return avail.next(it); } 
00107   index_t end() const { return avail.end(); } 
00108 };
00109 
00110 
00111 
00112 
00113 
00114 
00115 #endif //Aperios check
00116 
00117 #endif //INCLUDED
00118