00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <string.h>
00009 #include "converse.h"
00010 #include "conv-trace.h"
00011 #include "queueing.h"
00012 #include "conv-ccs.h"
00013 #include <errno.h>
00014
00015 CpvExtern(int, freezeModeFlag);
00016 CpvStaticDeclare(int, continueFlag);
00017 CpvStaticDeclare(int, stepFlag);
00018 CpvExtern(void *, debugQueue);
00019 CpvDeclare(void*, conditionalQueue);
00020 int conditionalPipe[2] = {0, 0};
00021 int _debugHandlerIdx;
00022
00023 char ** memoryBackup;
00024
00026 int _replaySystem = 0;
00027 int _conditionalDelivery = 0;
00028
00029 #undef ConverseDeliver
00030 int ConverseDeliver(int pe) {
00031 return !_replaySystem && (!_conditionalDelivery || pe==CmiMyPe());
00032 }
00033
00034 #if ! CMK_HAS_NTOHL
00035 uint32_t ntohl(uint32_t netlong) {
00036 union { uint32_t i; unsigned char c[4]; } uaw;
00037 uaw.i = netlong;
00038 netlong = uaw.c[0]<<24 + uaw.c[1]<<16 + uaw.c[2]<<8 + uaw.c[3];
00039 return netlong;
00040 }
00041 #endif
00042
00043
00044
00045
00046
00047 #include <string.h>
00048
00049 #include "pup_c.h"
00050
00051 CpvDeclare(int, CpdSearchLeaks_Index);
00052 CpvDeclare(int, CpdSearchLeaksDone_Index);
00053 CpvStaticDeclare(CcsDelayedReply, leakSearchDelayedReply);
00054
00055 void CpdSearchLeaksDone(void *msg) {
00056 CmiInt4 ok = 1;
00057 CcsSendDelayedReply(CpvAccess(leakSearchDelayedReply), 4, &ok);
00058 CmiFree(msg);
00059 }
00060
00061 void CpdSearchLeaks(char * msg) {
00062 LeakSearchInfo *info = (LeakSearchInfo *)(msg+CmiMsgHeaderSizeBytes);
00063 if (CmiMyPe() == info->pe || (info->pe == -1 && CmiMyPe() == 0)) {
00064 #if CMK_64BIT
00065 info->begin_data = (char*)(
00066 (((CmiUInt8)ntohl(((int*)&info->begin_data)[0]))<<32) + ntohl(((int*)&info->begin_data)[1]));
00067 info->end_data = (char*)(
00068 (((CmiUInt8)ntohl(((int*)&info->end_data)[0]))<<32) + ntohl(((int*)&info->end_data)[1]));
00069 info->begin_bss = (char*)(
00070 (((CmiUInt8)ntohl(((int*)&info->begin_bss)[0]))<<32) + ntohl(((int*)&info->begin_bss)[1]));
00071 info->end_bss = (char*)(
00072 (((CmiUInt8)ntohl(((int*)&info->end_bss)[0]))<<32) + ntohl(((int*)&info->end_bss)[1]));
00073 #else
00074 info->begin_data = (char*)(ntohl((int)info->begin_data));
00075 info->end_data = (char*)(ntohl((int)info->end_data));
00076 info->begin_bss = (char*)(ntohl((int)info->begin_bss));
00077 info->end_bss = (char*)(ntohl((int)info->end_bss));
00078 #endif
00079 info->quick = ntohl(info->quick);
00080 info->pe = ntohl(info->pe);
00081 CpvAccess(leakSearchDelayedReply) = CcsDelayReply();
00082 if (info->pe == -1) {
00083 CmiSetXHandler(msg, CpvAccess(CpdSearchLeaks_Index));
00084 CmiSetHandler(msg, _debugHandlerIdx);
00085 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+sizeof(LeakSearchInfo), msg);
00086 }
00087 }
00088 check_memory_leaks(info);
00089 if (info->pe == CmiMyPe()) CpdSearchLeaksDone(msg);
00090 else if (info->pe == -1) {
00091 void *reduceMsg = CmiAlloc(0);
00092 CmiSetHandler(reduceMsg, CpvAccess(CpdSearchLeaksDone_Index));
00093 CmiReduce(reduceMsg, CmiMsgHeaderSizeBytes, CmiReduceMergeFn_random);
00094 CmiFree(msg);
00095 }
00096 else CmiAbort("Received allocationTree request for another PE!");
00097 }
00098
00099 void * (*CpdDebugGetAllocationTree)(int *) = NULL;
00100 void (*CpdDebug_pupAllocationPoint)(pup_er p, void *data) = NULL;
00101 void (*CpdDebug_deleteAllocationPoint)(void *ptr) = NULL;
00102 void * (*CpdDebug_MergeAllocationTree)(int *size, void *data, void **remoteData, int numRemote) = NULL;
00103 CpvDeclare(int, CpdDebugCallAllocationTree_Index);
00104 CpvStaticDeclare(CcsDelayedReply, allocationTreeDelayedReply);
00105
00106 static void CpdDebugReturnAllocationTree(void *tree) {
00107 pup_er sizer = pup_new_sizer();
00108 char *buf;
00109 pup_er packer;
00110 int i;
00111 CpdDebug_pupAllocationPoint(sizer, tree);
00112 buf = (char *)malloc(pup_size(sizer));
00113 packer = pup_new_toMem(buf);
00114 CpdDebug_pupAllocationPoint(packer, tree);
00115
00116
00117
00118 CcsSendDelayedReply(CpvAccess(allocationTreeDelayedReply), pup_size(sizer),buf);
00119 pup_destroy(sizer);
00120 pup_destroy(packer);
00121 free(buf);
00122 }
00123
00124 static void CpdDebugCallAllocationTree(char *msg)
00125 {
00126 int numNodes;
00127 int forPE;
00128 void *tree;
00129 if (CpdDebugGetAllocationTree == NULL) {
00130 CmiPrintf("Error> Invoked CpdDebugCalloAllocationTree but no function initialized.\nDid you forget to link in memory charmdebug?\n");
00131 CcsSendReply(0, NULL);
00132 return;
00133 }
00134 sscanf(msg+CmiMsgHeaderSizeBytes, "%d", &forPE);
00135 if (CmiMyPe() == forPE) CpvAccess(allocationTreeDelayedReply) = CcsDelayReply();
00136 if (forPE == -1 && CmiMyPe()==0) {
00137 CpvAccess(allocationTreeDelayedReply) = CcsDelayReply();
00138 CmiSetXHandler(msg, CpvAccess(CpdDebugCallAllocationTree_Index));
00139 CmiSetHandler(msg, _debugHandlerIdx);
00140 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+strlen(msg+CmiMsgHeaderSizeBytes)+1, msg);
00141 }
00142 tree = CpdDebugGetAllocationTree(&numNodes);
00143 if (forPE == CmiMyPe()) CpdDebugReturnAllocationTree(tree);
00144 else if (forPE == -1) CmiReduceStruct(tree, CpdDebug_pupAllocationPoint, CpdDebug_MergeAllocationTree,
00145 CpdDebugReturnAllocationTree, CpdDebug_deleteAllocationPoint);
00146 else CmiAbort("Received allocationTree request for another PE!");
00147 CmiFree(msg);
00148 }
00149
00150 void * (*CpdDebugGetMemStat)(void) = NULL;
00151 void (*CpdDebug_pupMemStat)(pup_er p, void *data) = NULL;
00152 void (*CpdDebug_deleteMemStat)(void *ptr) = NULL;
00153 void * (*CpdDebug_mergeMemStat)(int *size, void *data, void **remoteData, int numRemote) = NULL;
00154 CpvDeclare(int, CpdDebugCallMemStat_Index);
00155 CpvStaticDeclare(CcsDelayedReply, memStatDelayedReply);
00156
00157 static void CpdDebugReturnMemStat(void *stat) {
00158 #if CMK_CCS_AVAILABLE
00159 pup_er sizerNet = pup_new_network_sizer();
00160 pup_er sizer = pup_new_fmt(sizerNet);
00161 char *buf;
00162 pup_er packerNet;
00163 pup_er packer;
00164 int i;
00165 CpdDebug_pupMemStat(sizer, stat);
00166 buf = (char *)malloc(pup_size(sizer));
00167 packerNet = pup_new_network_pack(buf);
00168 packer = pup_new_fmt(packerNet);
00169 CpdDebug_pupMemStat(packer, stat);
00170
00171
00172
00173 CcsSendDelayedReply(CpvAccess(memStatDelayedReply), pup_size(sizer),buf);
00174 pup_destroy(sizerNet);
00175 pup_destroy(sizer);
00176 pup_destroy(packerNet);
00177 pup_destroy(packer);
00178 free(buf);
00179 #endif
00180 }
00181
00182 static void CpdDebugCallMemStat(char *msg) {
00183 int forPE;
00184 void *stat;
00185 if (CpdDebugGetMemStat == NULL) {
00186 CmiPrintf("Error> Invoked CpdDebugCalloMemStat but no function initialized.\nDid you forget to link in memory charmdebug?\n");
00187 CcsSendReply(0, NULL);
00188 return;
00189 }
00190 sscanf(msg+CmiMsgHeaderSizeBytes, "%d", &forPE);
00191 if (CmiMyPe() == forPE) CpvAccess(memStatDelayedReply) = CcsDelayReply();
00192 if (forPE == -1 && CmiMyPe()==0) {
00193 CpvAccess(memStatDelayedReply) = CcsDelayReply();
00194 CmiSetXHandler(msg, CpvAccess(CpdDebugCallMemStat_Index));
00195 CmiSetHandler(msg, _debugHandlerIdx);
00196 CmiSyncBroadcast(CmiMsgHeaderSizeBytes+strlen(msg+CmiMsgHeaderSizeBytes)+1, msg);
00197 }
00198 stat = CpdDebugGetMemStat();
00199 if (forPE == CmiMyPe()) CpdDebugReturnMemStat(stat);
00200 else if (forPE == -1) CmiReduceStruct(stat, CpdDebug_pupMemStat, CpdDebug_mergeMemStat,
00201 CpdDebugReturnMemStat, CpdDebug_deleteMemStat);
00202 else CmiAbort("Received allocationTree request for another PE!");
00203 CmiFree(msg);
00204 }
00205
00206 static void CpdDebugHandlerStatus(char *msg) {
00207 #if ! CMK_NO_SOCKETS
00208 ChMessageInt_t reply[2];
00209 reply[0] = ChMessageInt_new(CmiMyPe());
00210 reply[1] = ChMessageInt_new(CpdIsFrozen() ? 0 : 1);
00211 CcsSendReply(2*sizeof(ChMessageInt_t), reply);
00212 #endif
00213 CmiFree(msg);
00214 }
00215
00216 static void CpdDebugHandlerFreeze(char *msg) {
00217 CpdFreeze();
00218 CmiFree(msg);
00219 }
00220
00221
00222
00223 void CpdNext(void) {
00224
00225 }
00226
00227
00228
00229
00230 void handleDebugMessage(void *msg) {
00231 CmiSetHandler(msg, CmiGetXHandler(msg));
00232 CmiHandleMessage(msg);
00233 }
00234
00235
00236
00237
00238 void CcsServerCheck(void);
00239 extern int _isCcsHandlerIdx(int idx);
00240 int (*CpdIsDebugMessage)(void *);
00241 void * (*CpdGetNextMessage)(CsdSchedulerState_t*);
00242
00243 void CpdFreezeModeScheduler(void)
00244 {
00245 #if CMK_BIGSIM_CHARM
00246 CmiAbort("Cannot run CpdFreezeModeScheduler inside BigSim emulated environment");
00247 #else
00248 #if CMK_CCS_AVAILABLE
00249 void *msg;
00250 void *debugQ=CpvAccess(debugQueue);
00251 CsdSchedulerState_t state;
00252 CsdSchedulerState_new(&state);
00253
00254
00255 while (CpvAccess(freezeModeFlag)) {
00256 #if NODE_0_IS_CONVHOST
00257 if (CmiMyPe()==0) CcsServerCheck();
00258 #endif
00259 msg = CpdGetNextMessage(&state);
00260
00261 if (msg!=NULL) {
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 if (conditionalPipe[1]!=0 && _conditionalDelivery==0) {
00275
00276 int bytes = SIZEFIELD(msg);
00277 write(conditionalPipe[1], &bytes, 4);
00278 write(conditionalPipe[1], msg, bytes);
00279 }
00280 if (CpdIsDebugMessage(msg)) {
00281 CmiHandleMessage(msg);
00282 }
00283 else
00284
00285 CdsFifo_Enqueue(debugQ, msg);
00286 } else CmiNotifyIdle();
00287 }
00288
00289
00290 while (!CdsFifo_Empty(debugQ))
00291 {
00292 char *queuedMsg = (char *)CdsFifo_Dequeue(debugQ);
00293 CmiHandleMessage(queuedMsg);
00294 }
00295 #endif
00296 #endif
00297 }
00298
00299 void CpdMemoryMarkClean(char *msg);
00300
00301 void CpdInit(void)
00302 {
00303 #if ! CMK_BIGSIM_CHARM
00304 CpvInitialize(int, freezeModeFlag);
00305 CpvAccess(freezeModeFlag) = 0;
00306
00307 CpvInitialize(void *, debugQueue);
00308 CpvAccess(debugQueue) = CdsFifo_Create();
00309 #endif
00310
00311 CpvInitialize(void *, conditionalQueue);
00312 CpvAccess(conditionalQueue) = CdsFifo_Create();
00313
00314 CcsRegisterHandler("debug/converse/freeze", (CmiHandler)CpdDebugHandlerFreeze);
00315 CcsRegisterHandler("debug/converse/status", (CmiHandler)CpdDebugHandlerStatus);
00316 CcsSetMergeFn("debug/converse/status", CcsMerge_concat);
00317
00318 CcsRegisterHandler("debug/memory/allocationTree", (CmiHandler)CpdDebugCallAllocationTree);
00319 CpvInitialize(int, CpdDebugCallAllocationTree_Index);
00320 CpvAccess(CpdDebugCallAllocationTree_Index) = CmiRegisterHandler((CmiHandler)CpdDebugCallAllocationTree);
00321
00322 CcsRegisterHandler("debug/memory/stat", (CmiHandler)CpdDebugCallMemStat);
00323 CpvInitialize(int, CpdDebugCallMemStat_Index);
00324 CpvAccess(CpdDebugCallMemStat_Index) = CmiRegisterHandler((CmiHandler)CpdDebugCallMemStat);
00325
00326 CcsRegisterHandler("debug/memory/leak",(CmiHandler)CpdSearchLeaks);
00327 CpvInitialize(int, CpdSearchLeaks_Index);
00328 CpvAccess(CpdSearchLeaks_Index) = CmiRegisterHandler((CmiHandler)CpdSearchLeaks);
00329 CpvInitialize(int, CpdSearchLeaksDone_Index);
00330 CpvAccess(CpdSearchLeaksDone_Index) = CmiRegisterHandler((CmiHandler)CpdSearchLeaksDone);
00331
00332 CcsRegisterHandler("debug/memory/mark",(CmiHandler)CpdMemoryMarkClean);
00333 CcsSetMergeFn("debug/memory/mark", CcsMerge_concat);
00334
00335 _debugHandlerIdx = CmiRegisterHandler((CmiHandler)handleDebugMessage);
00336 #if 0
00337 CpdInitializeObjectTable();
00338 CpdInitializeHandlerArray();
00339 CpdInitializeBreakPoints();
00340
00341
00342 msgListCleanup();
00343 msgListCache();
00344 #endif
00345
00346 }
00347