00001 #include <unistd.h>
00002 #include "middle.h"
00003
00004 #if CMK_BIGSIM_CHARM
00005 #include "bgconverse.h"
00006 #endif
00007 #include "ccs-server.h"
00008 #include "conv-ccs.h"
00009
00010 #ifdef _WIN32
00011 # include <sys/types.h>
00012 # include <io.h>
00013 # include <process.h>
00014 # define write _write
00015 # define getpid _getpid
00016 #endif
00017
00018 #if CMK_CCS_AVAILABLE
00019 void CcsHandleRequest(CcsImplHeader *hdr,const char *reqData);
00020
00021 void req_fw_handler(char *msg)
00022 {
00023 int offset = CmiReservedHeaderSize + sizeof(CcsImplHeader);
00024 CcsImplHeader *hdr = (CcsImplHeader *)(msg+CmiReservedHeaderSize);
00025 int destPE = (int)ChMessageInt(hdr->pe);
00026 if (CmiMyPe() == 0 && destPE == -1) {
00027
00028 int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+ChMessageInt(hdr->len);
00029 CmiSyncBroadcast(len, msg);
00030 }
00031 else if (destPE < -1) {
00032
00033 int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+ChMessageInt(hdr->len)-destPE*sizeof(ChMessageInt_t);
00034 int index, child, i;
00035 int *pes = (int*)(msg+CmiReservedHeaderSize+sizeof(CcsImplHeader));
00036 ChMessageInt_t *pes_nbo = (ChMessageInt_t *)pes;
00037 offset -= destPE * sizeof(ChMessageInt_t);
00038 if (ChMessageInt(pes_nbo[0]) == CmiMyPe()) {
00039 for (index=0; index<-destPE; ++index) pes[index] = ChMessageInt(pes_nbo[index]);
00040 }
00041 for (index=0; index<-destPE; ++index) {
00042 if (pes[index] == CmiMyPe()) break;
00043 }
00044 child = (index << 2) + 1;
00045 for (i=0; i<4; ++i) {
00046 if (child+i < -destPE) {
00047 CmiSyncSend(pes[child+i], len, msg);
00048 }
00049 }
00050 }
00051 CcsHandleRequest(hdr, msg+offset);
00052 CmiFree(msg);
00053 }
00054
00055 extern int rep_fw_handler_idx;
00060 int CcsReply(CcsImplHeader *rep,int repLen,const void *repData) {
00061 int repPE = (int)ChMessageInt(rep->pe);
00062 if (repPE <= -1) {
00063
00064 CcsHandlerRec *fn;
00065 int len=CmiReservedHeaderSize+sizeof(CcsImplHeader)+repLen;
00066 char *msg=(char*)CmiAlloc(len);
00067 char *r=msg+CmiReservedHeaderSize;
00068 char *handlerStr;
00069 rep->len = ChMessageInt_new(repLen);
00070 *(CcsImplHeader *)r=*rep; r+=sizeof(CcsImplHeader);
00071 memcpy(r,repData,repLen);
00072 CmiSetHandler(msg,rep_fw_handler_idx);
00073 handlerStr=rep->handler;
00074 fn=(CcsHandlerRec *)CcsGetHandler(handlerStr);
00075 if (fn->mergeFn == NULL) CmiAbort("Called CCS broadcast with NULL merge function!\n");
00076 if (repPE == -1) {
00077
00078 CkReduce(msg, len, fn->mergeFn);
00079 } else {
00080
00081 CmiListReduce(-repPE, (int*)(rep+1), msg, len, fn->mergeFn, fn->redID);
00082 }
00083 } else {
00084 if (_conditionalDelivery == 0) CcsImpl_reply(rep, repLen, repData);
00085 else {
00086
00087 if (write(conditionalPipe[1], &repLen, 4) != 4) {
00088 CmiAbort("CCS> writing reply length to parent failed!");
00089 }
00090 if (write(conditionalPipe[1], repData, repLen) != repLen) {
00091 CmiAbort("CCS> writing reply data to parent failed!");
00092 }
00093 }
00094 }
00095 return 0;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 void ccs_getinfo(char *msg)
00107 {
00108 int nNode=CmiNumNodes();
00109 int len=(1+nNode)*sizeof(ChMessageInt_t);
00110 ChMessageInt_t *table=(ChMessageInt_t *)malloc(len);
00111 int n;
00112 table[0]=ChMessageInt_new(nNode);
00113 for (n=0;n<nNode;n++)
00114 table[1+n]=ChMessageInt_new(CmiNodeSize(n));
00115 CcsSendReply(len,(const char *)table);
00116 free(table);
00117 CmiFree(msg);
00118 }
00119
00121 #endif
00122 #if ! CMK_HAS_GETPID
00123 typedef int pid_t;
00124 #endif
00125
00126 CpvCExtern(void *, debugQueue);
00127 CpvDeclare(void *, debugQueue);
00128 CpvCExtern(int, freezeModeFlag);
00129 CpvDeclare(int, freezeModeFlag);
00130
00131
00132
00133
00134
00135 void CpdFreeze(void)
00136 {
00137 pid_t pid = 0;
00138 #if CMK_HAS_GETPID
00139 pid = getpid();
00140 #endif
00141 CpdNotify(CPD_FREEZE,pid);
00142 if (CpvAccess(freezeModeFlag)) return;
00143 CpvAccess(freezeModeFlag) = 1;
00144 #if ! CMK_BIGSIM_CHARM
00145 CpdFreezeModeScheduler();
00146 #endif
00147 }
00148
00149 void CpdUnFreeze(void)
00150 {
00151 CpvAccess(freezeModeFlag) = 0;
00152 }
00153
00154 int CpdIsFrozen(void) {
00155 return CpvAccess(freezeModeFlag);
00156 }
00157
00158 #if CMK_BIGSIM_CHARM
00159 #include "blue_impl.h"
00160 void BgProcessMessageFreezeMode(threadInfo *t, char *msg) {
00161
00162 #if CMK_CCS_AVAILABLE
00163 void *debugQ=CpvAccess(debugQueue);
00164 CmiAssert(msg!=NULL);
00165 int processImmediately = CpdIsDebugMessage(msg);
00166 if (processImmediately) BgProcessMessageDefault(t, msg);
00167 while (!CpvAccess(freezeModeFlag) && !CdsFifo_Empty(debugQ)) {
00168 BgProcessMessageDefault(t, (char*)CdsFifo_Dequeue(debugQ));
00169 }
00170 if (!processImmediately) {
00171 if (!CpvAccess(freezeModeFlag)) BgProcessMessageDefault(t, msg);
00172 else CdsFifo_Enqueue(debugQ, msg);
00173 }
00174 #else
00175 BgProcessMessageDefault(t, msg);
00176 #endif
00177 }
00178 #endif
00179
00180 void PrintDebugStackTrace(void *);
00181 void * MemoryToSlot(void *ptr);
00182 int Slot_StackTrace(void *s, void ***stack);
00183 int Slot_ChareOwner(void *s);
00184
00185 #include <stdarg.h>
00186 void CpdNotify(int type, ...) {
00187 void *ptr; int integer, i;
00188 pid_t pid=0;
00189 int levels=64;
00190 void *stackPtrs[64];
00191 void *sl;
00192 va_list list;
00193 va_start(list, type);
00194 switch (type) {
00195 case CPD_ABORT:
00196 CmiPrintf("CPD: %d Abort %s\n",CmiMyPe(), va_arg(list, char*));
00197 break;
00198 case CPD_SIGNAL:
00199 CmiPrintf("CPD: %d Signal %d\n",CmiMyPe(), va_arg(list, int));
00200 break;
00201 case CPD_FREEZE:
00202 #if CMK_HAS_GETPID
00203 pid = getpid();
00204 #endif
00205 CmiPrintf("CPD: %d Freeze %d\n",CmiMyPe(),pid);
00206 break;
00207 case CPD_BREAKPOINT:
00208 CmiPrintf("CPD: %d BP %s\n",CmiMyPe(), va_arg(list, char*));
00209 break;
00210 case CPD_CROSSCORRUPTION:
00211 ptr = va_arg(list, void*);
00212 integer = va_arg(list, int);
00213 CmiPrintf("CPD: %d Cross %p %d ",CmiMyPe(), ptr, integer);
00214 sl = MemoryToSlot(ptr);
00215 if (sl != NULL) {
00216 int stackLen; void **stackTrace;
00217 stackLen = Slot_StackTrace(sl, &stackTrace);
00218 CmiPrintf("%d %d ",Slot_ChareOwner(sl),stackLen);
00219 for (i=0; i<stackLen; ++i) CmiPrintf("%p ",stackTrace[i]);
00220 } else {
00221 CmiPrintf("0 ");
00222 }
00223 CmiBacktraceRecord(stackPtrs,1,&levels);
00224 CmiPrintf("%d ",levels);
00225 for (i=0; i<levels; ++i) CmiPrintf("%p ",stackPtrs[i]);
00226 CmiPrintf("\n");
00227 break;
00228 }
00229 va_end(list);
00230 }