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