00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef SST_CORE_ACTIVITY_H
00014 #define SST_CORE_ACTIVITY_H
00015
00016 #include <sst/core/sst_types.h>
00017 #include <sst/core/serialization.h>
00018
00019 #include <sst/core/output.h>
00020 #include <sst/core/mempool.h>
00021
00022 #include <cstring>
00023 #include <errno.h>
00024
00025
00026 #define STOPACTIONPRIORITY 01
00027 #define SYNCPRIORITY 25
00028 #define INTROSPECTPRIORITY 30
00029 #define CLOCKPRIORITY 40
00030 #define EVENTPRIORITY 50
00031 #define MEMEVENTPRIORITY 50
00032 #define BARRIERPRIORITY 75
00033 #define ONESHOTPRIORITY 80
00034 #define STATISTICCLOCKPRIORITY 85
00035 #define FINALEVENTPRIORITY 98
00036 #define EXITPRIORITY 99
00037
00038 namespace SST {
00039
00040
00041 class Activity {
00042 public:
00043 Activity() {}
00044 virtual ~Activity() {}
00045
00046
00047 virtual void execute(void) = 0;
00048
00049
00050 class less_time_priority {
00051 public:
00052
00053 inline bool operator()(const Activity* lhs, const Activity* rhs) {
00054 if (lhs->delivery_time == rhs->delivery_time ) return lhs->priority < rhs->priority;
00055 else return lhs->delivery_time < rhs->delivery_time;
00056 }
00057
00058
00059 inline bool operator()(const Activity& lhs, const Activity& rhs) {
00060 if (lhs.delivery_time == rhs.delivery_time ) return lhs.priority < rhs.priority;
00061 else return lhs.delivery_time < rhs.delivery_time;
00062 }
00063 };
00064
00065
00066 class pq_less_time_priority {
00067 public:
00068
00069 inline bool operator()(const Activity* lhs, const Activity* rhs) const {
00070 if ( lhs->delivery_time == rhs->delivery_time ) {
00071 if ( lhs->priority == rhs->priority ) {
00072
00073 return lhs->queue_order > rhs->queue_order;
00074 }
00075 return lhs->priority > rhs->priority;
00076 }
00077 return lhs->delivery_time > rhs->delivery_time;
00078 }
00079
00080
00081 inline bool operator()(const Activity& lhs, const Activity& rhs) {
00082 if ( lhs.delivery_time == rhs.delivery_time ) {
00083 if ( lhs.priority == rhs.priority ) {
00084
00085 return lhs.queue_order > rhs.queue_order;
00086 }
00087 return lhs.priority > rhs.priority;
00088 }
00089 return lhs.delivery_time > rhs.delivery_time;
00090 }
00091 };
00092
00093
00094 class less_time {
00095 public:
00096
00097 inline bool operator()(const Activity* lhs, const Activity* rhs) {
00098 return lhs->delivery_time < rhs->delivery_time;
00099 }
00100
00101
00102 inline bool operator()(const Activity& lhs, const Activity& rhs) {
00103 return lhs.delivery_time < rhs.delivery_time;
00104 }
00105 };
00106
00107
00108 void setDeliveryTime(SimTime_t time) {
00109 delivery_time = time;
00110 }
00111
00112
00113 inline SimTime_t getDeliveryTime() const {
00114 return delivery_time;
00115 }
00116
00117
00118 inline int getPriority() const {
00119 return priority;
00120 }
00121
00122
00123
00124
00125 virtual void print(const std::string& header, Output &out) const {
00126 out.output("%s Generic Activity to be delivered at %" PRIu64 " with priority %d\n",
00127 header.c_str(), delivery_time, priority);
00128 }
00129
00130 #ifdef __SST_DEBUG_EVENT_TRACKING__
00131 virtual void printTrackingInfo(const std::string& header, Output &out) const {
00132 }
00133 #endif
00134
00135
00136 void setQueueOrder(uint64_t order) {
00137 queue_order = order;
00138 }
00139
00140 #ifdef USE_MEMPOOL
00141
00142 void* operator new(std::size_t size) throw()
00143 {
00144
00145
00146
00147
00148
00149 size_t poolSize = memPools.size();
00150 Core::MemPool *pool = NULL;
00151 uint32_t poolID = 0;
00152 for ( uint32_t i = 0 ; i < poolSize ; i++ ) {
00153 if ( memPools[i].first == size ) {
00154 pool = memPools[i].second;
00155 poolID = i;
00156 break;
00157 }
00158 }
00159 if ( NULL == pool ) {
00160
00161 pool = new Core::MemPool(size+sizeof(uint32_t));
00162 memPools.push_back(std::make_pair(size, pool));
00163 poolID = memPools.size() - 1;
00164 }
00165 uint32_t *ptr = (uint32_t*)pool->malloc();
00166 if ( !ptr ) {
00167 fprintf(stderr, "Memory Pool failed to allocate a new object. Error: %s\n", strerror(errno));
00168 return NULL;
00169 }
00170 *ptr = poolID;
00171 return (void*)(ptr+1);
00172 }
00173
00174
00175
00176 void operator delete(void* ptr)
00177 {
00178
00179
00180
00181
00182
00183 uint32_t *ptr8 = ((uint32_t*)ptr) - 1;
00184 uint32_t poolID = *ptr8;
00185 *ptr8 = 0xffffffff;
00186 Core::MemPool* pool = memPools[poolID].second;
00187
00188 pool->free(ptr8);
00189 }
00190 void operator delete(void* ptr, std::size_t sz){
00191
00192
00193
00194
00195 uint32_t *ptr8 = ((uint32_t*)ptr) - 1;
00196 uint32_t poolID = *ptr8;
00197 *ptr8 = 0xffffffff;
00198 Core::MemPool* pool = memPools[poolID].second;
00199
00200 pool->free(ptr8);
00201 };
00202
00203 static void getMemPoolUsage(uint64_t& bytes, uint64_t& active_activities) {
00204 bytes = 0;
00205 active_activities = 0;
00206 for ( uint32_t i = 0; i < Activity::memPools.size(); i++ ) {
00207 std::pair<size_t, Core::MemPool*> entry = Activity::memPools[i];
00208 bytes += entry.second->getBytesMemUsed();
00209 active_activities += entry.second->getUndeletedEntries();
00210 }
00211 }
00212
00213 static void printUndeletedActivites(const std::string& header, Output &out, SimTime_t before = MAX_SIMTIME_T) {
00214 for ( uint32_t i = 0; i < Activity::memPools.size(); i++ ) {
00215 std::pair<size_t, Core::MemPool*> entry = Activity::memPools[i];
00216 const std::list<uint8_t*>& arenas = entry.second->getArenas();
00217 size_t arenaSize = entry.second->getArenaSize();
00218 size_t elemSize = entry.second->getElementSize();
00219 size_t nelem = arenaSize / elemSize;
00220 for ( auto iter = arenas.begin(); iter != arenas.end(); ++iter ) {
00221 for ( size_t j = 0; j < nelem; j++ ) {
00222 uint32_t* ptr = (uint32_t*)((*iter) + (elemSize*j));
00223 if ( *ptr != 0xFFFFFFFF ) {
00224 Activity* act = (Activity*)(ptr + 1);
00225 if ( act->delivery_time <= before ) {
00226 act->print(header, out);
00227 #ifdef __SST_DEBUG_EVENT_TRACKING__
00228 act->printTrackingInfo(header + " ", out);
00229 #endif
00230 }
00231 }
00232 }
00233 }
00234 }
00235 }
00236
00237 #endif
00238
00239
00240 protected:
00241
00242 void setPriority(int priority) {
00243 this->priority = priority;
00244 }
00245
00246
00247 private:
00248 uint64_t queue_order;
00249 SimTime_t delivery_time;
00250 int priority;
00251 #ifdef USE_MEMPOOL
00252 static std::vector<std::pair<size_t, Core::MemPool*> > memPools;
00253 #endif
00254
00255 friend class boost::serialization::access;
00256 template<class Archive>
00257 void
00258 serialize(Archive & ar, const unsigned int version )
00259 {
00260 ar & BOOST_SERIALIZATION_NVP(delivery_time);
00261 ar & BOOST_SERIALIZATION_NVP(priority);
00262 }
00263 };
00264
00265 }
00266
00267 BOOST_CLASS_EXPORT_KEY(SST::Activity)
00268
00269 #endif // SST_CORE_ACTIVITY_H