static int sort_Gid (const void *e1, const void *e2) { REGISTER JIPartner *item1 = (JIPartner *)e1; REGISTER JIPartner *item2 = (JIPartner *)e2; if (OBJ_GID(item1->hdr) < OBJ_GID(item2->hdr)) return(-1); if (OBJ_GID(item1->hdr) > OBJ_GID(item2->hdr)) return(1); return(0); }
void DDD_JoinObj (DDD_HDR hdr, DDD_PROC dest, DDD_GID new_gid) { JIJoin *ji; if (!ddd_JoinActive()) { DDD_PrintError('E', 7012, "Missing DDD_JoinBegin(). aborted"); HARD_EXIT; } if (dest>=procs) { sprintf(cBuffer, "cannot join %08x with %08x on processor %d (procs=%d)", OBJ_GID(hdr), new_gid, dest, procs); DDD_PrintError('E', 7003, cBuffer); HARD_EXIT; } if (dest==me) { sprintf(cBuffer, "cannot join %08x with myself", OBJ_GID(hdr)); DDD_PrintError('E', 7004, cBuffer); HARD_EXIT; } if (ObjHasCpl(hdr)) { sprintf(cBuffer, "cannot join %08x, object already distributed", OBJ_GID(hdr)); DDD_PrintError('E', 7005, cBuffer); HARD_EXIT; } ji = JIJoinSet_NewItem(joinGlobals.setJIJoin); ji->hdr = hdr; ji->dest = dest; ji->new_gid = new_gid; if (! JIJoinSet_ItemOK(joinGlobals.setJIJoin)) return; # if DebugJoin<=2 sprintf(cBuffer, "%4d: DDD_JoinObj %08x, dest=%d, new_gid=%08x\n", me, OBJ_GID(hdr), dest, new_gid); DDD_PrintDebug(cBuffer); # endif }
static void UnpackPhase3Msgs (LC_MSGHANDLE *theMsgs, int nRecvMsgs, JIJoinPtrArray *arrayJoin) { JIJoin **itemsJ = JIJoinPtrArray_GetData(arrayJoin); int nJ = JIJoinPtrArray_GetSize(arrayJoin); int m; for(m=0; m<nRecvMsgs; m++) { LC_MSGHANDLE jm = theMsgs[m]; TEAddCpl *theAC = (TEAddCpl *) LC_GetPtr(jm, joinGlobals.cpltab_id); int nAC = (int) LC_GetTableLen(jm, joinGlobals.cpltab_id); int i, j; for(i=0, j=0; i<nAC; i++) { while ((j<nJ) && (OBJ_GID(itemsJ[j]->hdr) < theAC[i].gid)) j++; if ((j<nJ) && (OBJ_GID(itemsJ[j]->hdr) == theAC[i].gid)) { /* found local object which is AddCpl target */ AddCoupling(itemsJ[j]->hdr, theAC[i].proc, theAC[i].prio); # if DebugJoin<=1 printf("%4d: Phase3 execute AddCpl(%08x,%d,%d) (from %d).\n", me, OBJ_GID(itemsJ[j]->hdr), theAC[i].proc, theAC[i].prio, LC_MsgGetProc(jm)); # endif } else { /* this should never happen. AddCpl send for unknown obj. */ assert(0); } } } }
static void XferPackSingleMsg (XFERMSG *msg) { SYMTAB_ENTRY *theSymTab; OBJTAB_ENTRY *theObjTab; TENewCpl *theNewCpl; TEOldCpl *theOldCpl; char *theObjects, *currObj; int i, actSym, actNewCpl, actOldCpl, actObj, recvProc; INT mi; /* recipient of this message */ recvProc = msg->proc; /* get table addresses inside message */ theSymTab = (SYMTAB_ENTRY *)LC_GetPtr(msg->msg_h, xferGlobals.symtab_id); theObjTab = (OBJTAB_ENTRY *)LC_GetPtr(msg->msg_h, xferGlobals.objtab_id); theNewCpl = (TENewCpl *) LC_GetPtr(msg->msg_h, xferGlobals.newcpl_id); theOldCpl = (TEOldCpl *) LC_GetPtr(msg->msg_h, xferGlobals.oldcpl_id); theObjects= (char *)LC_GetPtr(msg->msg_h, xferGlobals.objmem_id); /* build several tables inside message */ actSym = actNewCpl = actOldCpl = actObj = 0; currObj = theObjects; for(i=0; i<msg->nObjItems; i++) /* for all XICopyObj-items */ { REGISTER XICopyObj *xi = msg->xferObjArray[i]; REGISTER DDD_HDR hdr = xi->hdr; TYPE_DESC *desc = &theTypeDefs[OBJ_TYPE(hdr)]; DDD_OBJ obj = HDR2OBJ(hdr,desc); /*COUPLING *cpl;*/ DDD_HDR copyhdr; /* build coupling table */ /* skip cpl which describes object itself (receive proc) */ /* for(cpl=THECOUPLING(hdr); cpl!=NULL; cpl=cpl->next) { if (cpl->proc!=recvProc) { theNewCpl[actNewCpl].gid = OBJ_GID(hdr); theNewCpl[actNewCpl].proc = cpl->proc; theNewCpl[actNewCpl].prio = cpl->prio; actNewCpl++; } } */ /* one coupling for object itself (send proc) */ /* theNewCpl[actNewCpl].gid = OBJ_GID(hdr); theNewCpl[actNewCpl].proc = me; theNewCpl[actNewCpl].prio = OBJ_PRIO(hdr); actNewCpl++; */ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) copyhdr = OBJ2HDR(currObj,desc); #else copyhdr = (DDD_HDR) currObj; #endif /* update object table */ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) theObjTab[actObj].h_offset = (int)(((char *)copyhdr)-theObjects); #else theObjTab[actObj].o_offset = (int)(currObj-theObjects); theObjTab[actObj].typ = OBJ_TYPE(hdr); theObjTab[actObj].gid = OBJ_GID(hdr); theObjTab[actObj].attr = OBJ_ATTR(hdr); theObjTab[actObj].prio = xi->prio; #endif theObjTab[actObj].hdr = NULL; theObjTab[actObj].addLen = xi->addLen; theObjTab[actObj].size = xi->size; /* needed for variable-sized objects */ actObj++; /* copy object into message. in the following xi->size equals desc->len for fixed-size objects. */ /*STAT_RESET3;*/ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) /* NOTE: object memory is copied _completely_, i.e., also LDATA- components are copied into message and sent to destination. then, on the receiving processor the data is sorted out... */ memcpy(currObj, obj, xi->size); #else ObjToMsg (obj, desc, currObj); #endif /*STAT_INCTIMER3(32);*/ /* insert priority into copy */ OBJ_PRIO(copyhdr) = xi->prio; /* call application handler for direct manipulation */ /* KB 941110: moved from objmgr.c */ /* Caution: this is a very, very dirty situation. HANDLER_XFERCOPYMANIP is able to manipulate the obj-copy inside the message. this handler should be removed in future DDD versions. */ #if defined(C_FRONTEND) if (desc->handlerXFERCOPYMANIP) { /* NOTE: OBJ_TYPE could change during the execution of HANDLER_XFERCOPYMANIP. however, the position of DDD_HEADER inside the object should not change. therefore, we can remember the offsetHeader here and use it afterwards to adjust the desc. */ int offset = desc->offsetHeader; /* now call handler */ desc->handlerXFERCOPYMANIP(currObj); /* adjust new description according to new type */ desc = &(theTypeDefs[OBJ_TYPE((DDD_HDR)(currObj+offset))]); } #endif /* build symbol table portion from object copy */ actSym += BuildSymTab(desc, obj, (char *)currObj, &(theSymTab[actSym])); /* advance to next free object slot in message, c.f. alignment */ currObj += CEIL(xi->size); /* gather additional data */ if (xi->addLen>0) { actSym += GetDepData(currObj, desc, obj, &(theSymTab[actSym]), xi); currObj += xi->addLen; } } /* for all XINewCpl items in this message */ for(i=0; i<msg->nNewCpl; i++) { theNewCpl[actNewCpl] = msg->xferNewCpl[i]->te; actNewCpl++; } /* for all XIOldCpl items in this message */ for(i=0; i<msg->nOldCpl; i++) { theOldCpl[actOldCpl] = msg->xferOldCpl[i]->te; actOldCpl++; } /* sort SymTab, ObjTab and CplTab */ /*STAT_RESET3;*/ qsort(theSymTab, actSym, sizeof(SYMTAB_ENTRY), sort_SymTabEntries); /*STAT_INCTIMER3(34); STAT_RESET3;*/ /* sorting of objtab is necessary!! (see AcceptObjFromMsg) KB 960812 */ currentObjectMem = theObjects; qsort(theObjTab, msg->nObjects, sizeof(OBJTAB_ENTRY), sort_ObjTabEntries); /*STAT_INCTIMER3(35); STAT_RESET3;*/ #ifdef SORT_STATISTIK sprintf(cBuffer, "ITEMS 34=%d, 35=%d, 36=%d\n", actSym, msg->nObjects, actNewCpl); DDD_PrintDebug(cBuffer); sprintf(cBuffer, "COMPS 34=%d, 35=%d, 36=%d\n", n34, n35, n36); DDD_PrintDebug(cBuffer); #endif /* substitute all pointers by index into SymTab */ /*TAT_RESET3;*/ for(mi=0; mi<actSym; mi++) { /* patch SymTab index into reference location inside message */ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) *(theSymTab[mi].adr.ref) = (DDD_OBJ)(mi+1); #endif #ifdef F_FRONTEND *(theSymTab[mi].adr.ref) = (mi+1); #endif } /*STAT_INCTIMER3(37);*/ /* TODO: theSymtab[].ref wird ab hier nicht mehr verwendet und muss nicht uebertragen werden! */ /* set valid table entries */ LC_SetTableLen(msg->msg_h, xferGlobals.symtab_id, actSym); LC_SetTableLen(msg->msg_h, xferGlobals.objtab_id, msg->nObjects); LC_SetTableLen(msg->msg_h, xferGlobals.newcpl_id, actNewCpl); LC_SetTableLen(msg->msg_h, xferGlobals.oldcpl_id, actOldCpl); #if DebugXfer>1 if (DDD_GetOption(OPT_DEBUG_XFERMESGS)==OPT_ON) #endif XferDisplayMsg("OS", msg->msg_h); }
static int BuildSymTab (TYPE_DESC *desc, DDD_OBJ obj, char *copy, SYMTAB_ENTRY *theSymTab) { ELEM_DESC *theElem; int e, actSym; /*STAT_RESET4;*/ /* reset local portion of SymTab */ actSym = 0; /* prepare map of structure elements */ theElem = desc->element; /* loop over all pointers inside of object obj */ for(e=0; e<desc->nElements; e++, theElem++) { if (theElem->type==EL_OBJPTR) { TYPE_DESC *refdesc; int l; int rt_on_the_fly = (EDESC_REFTYPE(theElem)==DDD_TYPE_BY_HANDLER); /* determine reftype of this elem */ if (! rt_on_the_fly) { /* we know the reftype of this element in advance */ refdesc = &theTypeDefs[EDESC_REFTYPE(theElem)]; } /* else: determine reftype on the fly by calling handler */ /* loop over single pointer array */ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) for(l=0; l<theElem->size; l+=sizeof(void *)) { /* get address of outside reference */ DDD_OBJ *ref = (DDD_OBJ *)(copy+theElem->offset+l); #else for(l=0; l<theElem->size; l+=sizeof(DDD_OBJ)) { /* F77TODO: DDD_OBJ* must be replaced by local objindex */ /* get the index of the referenced object */ DDD_OBJ *ref = (DDD_OBJ *)(copy+theElem->msgoffset); #endif /* create symbol table entry */ if (*ref!=NULL) { DDD_HDR refhdr; if (rt_on_the_fly) { DDD_TYPE rt; /* determine reftype on the fly by calling handler */ assert(obj!=NULL); /* we need a real object here */ rt = theElem->reftypeHandler(obj, *ref); if (rt>=MAX_TYPEDESC) { DDD_PrintError('E', 6520, "invalid referenced DDD_TYPE " "returned by handler"); HARD_EXIT; } refdesc = &theTypeDefs[rt]; } /* get header of referenced object */ refhdr = OBJ2HDR(*ref,refdesc); /* remember the GID of the referenced object */ theSymTab[actSym].gid = OBJ_GID(refhdr); /* remember the address of the reference (in obj-copy) */ theSymTab[actSym].adr.ref = ref; actSym++; } } } } /*STAT_INCTIMER4(33);*/ /* return SymTab increment */ return(actSym); } /****************************************************************************/ /* */ /* Function: GetDepData */ /* */ /* Purpose: fill object-dependent data into message. an appl. routine */ /* will be called to fill in the data actually. pointers are */ /* localized and the message SymTab is actualized. */ /* */ /* Input: data: portion of message buffer reserved for dependent data */ /* desc: descriptor of object */ /* obj: current ddd-object */ /* theSymTab: actual portion of message SymTab */ /* xi: single xferinfo for current ddd-object */ /* */ /* Output: number of new entries into SymTab */ /* */ /****************************************************************************/ static int GetDepData (char *data, TYPE_DESC *desc, DDD_OBJ obj, SYMTAB_ENTRY *theSymTab, XICopyObj *xi) { XFERADDDATA *xa; TYPE_DESC *descDep; char *chunk, *adr, **table1, *next_chunk; int chunks, i, actSym, *table2; if (xi->addLen==0) return(0); chunks = 0; actSym = 0; /* first entry will be number of dependency chunks */ chunk = data + CEIL(sizeof(int)); /* loop through whole dependency data descriptor */ for(xa=xi->add; xa!=NULL; xa=xa->next) { /* first entries of chunk are addCnt and addTyp */ ((int *)chunk)[0] = xa->addCnt; ((DDD_TYPE *)chunk)[1] = xa->addTyp; if (xa->sizes==NULL) { chunk += CEIL(sizeof(int)+sizeof(DDD_TYPE)); /* then all records should be gathered via handler */ if (desc->handlerXFERGATHER) { #if defined(C_FRONTEND) || defined(F_FRONTEND) desc->handlerXFERGATHER(_FADR obj, _FADR xa->addCnt, _FADR xa->addTyp, (void *)chunk); #endif #ifdef CPP_FRONTEND CallHandler(desc,XFERGATHER) (HParam(obj) xa->addCnt, xa->addTyp, (void *)chunk); #endif } if (xa->addTyp<DDD_USER_DATA || xa->addTyp>DDD_USER_DATA_MAX) { /* insert pointers into symtab */ descDep = &theTypeDefs[xa->addTyp]; for(i=0; i<xa->addCnt; i++) { actSym += BuildSymTab(descDep, NULL, chunk, &(theSymTab[actSym])); chunk += CEIL(descDep->size); } } else { /* no regular type -> send byte stream with length addCnt */ chunk += CEIL(xa->addCnt); } } else { /* var-sized AddData items */ ((int *)chunk)[0] *= -1; chunk += CEIL(sizeof(int)+sizeof(DDD_TYPE)); /* create pointer array inside message */ table1 = (char **)chunk; chunk += CEIL(sizeof(int)*xa->addCnt); for(i=0, adr=chunk; i<xa->addCnt; i++) { table1[i] = adr; adr += CEIL(xa->sizes[i]); } next_chunk = adr; /* then all records should be gathered via handler */ if (desc->handlerXFERGATHERX) { #if defined(C_FRONTEND) || defined(F_FRONTEND) desc->handlerXFERGATHERX(_FADR obj, _FADR xa->addCnt, _FADR xa->addTyp, table1); #endif #ifdef CPP_FRONTEND CallHandler(desc,XFERGATHERX) (HParam(obj) xa->addCnt, xa->addTyp, table1); #endif } /* convert pointer table into offset table */ table2 = (int *)table1; descDep = &theTypeDefs[xa->addTyp]; adr = chunk; for(i=0; i<xa->addCnt; i++) { /* insert pointers into symtab */ if (xa->addTyp<DDD_USER_DATA || xa->addTyp>DDD_USER_DATA_MAX) { actSym += BuildSymTab(descDep, NULL, table1[i], &(theSymTab[actSym])); } table2[i] = (int)(table1[i]-adr); } chunk = next_chunk; } /* count chunks */ chunks++; } /* remember number of chunks at the beginning of the deplist */ ((int *)data)[0] = chunks; return(actSym); }
void Method(Print) (ParamThis _PRINTPARAMS) { fprintf(fp, "JIJoin local_gid=%08x dest=%d new_gid=%08x\n", OBJ_GID(This->hdr), This->dest, This->new_gid); }
static void UnpackPhase2Msgs (LC_MSGHANDLE *theMsgs2, int nRecvMsgs2, JIPartner *joinObjs, int nJoinObjs, DDD_HDR *localCplObjs, int nLCO) { int m; for(m=0; m<nRecvMsgs2; m++) { LC_MSGHANDLE jm = theMsgs2[m]; TEAddCpl *theAC = (TEAddCpl *) LC_GetPtr(jm, joinGlobals.addtab_id); int nAC = (int) LC_GetTableLen(jm, joinGlobals.addtab_id); int i, j, jo; for(i=0, j=0, jo=0; i<nAC; i++) { while ((j<nLCO) && (OBJ_GID(localCplObjs[j]) < theAC[i].gid)) j++; while ((jo<nJoinObjs) && (OBJ_GID(joinObjs[jo].hdr) < theAC[i].gid)) jo++; if ((j<nLCO) && (OBJ_GID(localCplObjs[j])==theAC[i].gid)) { /* found local object which is AddCpl target */ AddCoupling(localCplObjs[j], theAC[i].proc, theAC[i].prio); # if DebugJoin<=1 printf("%4d: Phase2 execute AddCpl(%08x,%d,%d) (from %d).\n", me, theAC[i].gid, theAC[i].proc, theAC[i].prio, LC_MsgGetProc(jm)); # endif while ((jo<nJoinObjs) && (OBJ_GID(joinObjs[jo].hdr) == theAC[i].gid)) { JIAddCpl *ji = JIAddCplSet_NewItem(joinGlobals.setJIAddCpl3); ji->dest = joinObjs[jo].proc; ji->te.gid = theAC[i].gid; ji->te.proc = theAC[i].proc; ji->te.prio = theAC[i].prio; JIAddCplSet_ItemOK(joinGlobals.setJIAddCpl3); # if DebugJoin<=1 printf("%4d: Phase2 forward AddCpl(%08x,%d,%d) to %d.\n", me, theAC[i].gid, theAC[i].proc, theAC[i].prio, ji->dest); # endif jo++; } } else { /* this should never happen. AddCpl send from invalid proc. */ assert(0); } } } }
static void UnpackPhase1Msgs (LC_MSGHANDLE *theMsgs, int nRecvMsgs, DDD_HDR *localCplObjs, int nLCO, JIPartner **p_joinObjs, int *p_nJoinObjs) { JIPartner *joinObjs; int nJoinObjs = 0; int m, jo; /* init return values */ *p_joinObjs = NULL; *p_nJoinObjs = 0; for(m=0; m<nRecvMsgs; m++) { LC_MSGHANDLE jm = theMsgs[m]; TEJoin *theJoin = (TEJoin *) LC_GetPtr(jm, joinGlobals.jointab_id); int nJ = (int) LC_GetTableLen(jm, joinGlobals.jointab_id); int i, j; nJoinObjs += nJ; for(i=0, j=0; i<nJ; i++) { while ((j<nLCO) && (OBJ_GID(localCplObjs[j]) < theJoin[i].gid)) j++; if ((j<nLCO) && (OBJ_GID(localCplObjs[j])==theJoin[i].gid)) { COUPLING *cpl; /* found local object which is join target */ /* store shortcut to local object */ theJoin[i].hdr = localCplObjs[j]; /* generate phase2-JIAddCpl for this object */ for(cpl=ObjCplList(localCplObjs[j]); cpl!=NULL; cpl=CPL_NEXT(cpl)) { JIAddCpl *ji = JIAddCplSet_NewItem(joinGlobals.setJIAddCpl2); ji->dest = CPL_PROC(cpl); ji->te.gid = theJoin[i].gid; ji->te.proc = LC_MsgGetProc(jm); ji->te.prio = theJoin[i].prio; if (! JIAddCplSet_ItemOK(joinGlobals.setJIAddCpl2)) continue; # if DebugJoin<=1 printf("%4d: Phase1 Join for %08x from %d, " "send AddCpl to %d.\n", me, theJoin[i].gid, ji->te.proc, ji->dest); # endif } /* send phase3-JIAddCpl back to Join-proc */ for(cpl=ObjCplList(localCplObjs[j]); cpl!=NULL; cpl=CPL_NEXT(cpl)) { JIAddCpl *ji = JIAddCplSet_NewItem(joinGlobals.setJIAddCpl3); ji->dest = LC_MsgGetProc(jm); ji->te.gid = OBJ_GID(localCplObjs[j]); ji->te.proc = CPL_PROC(cpl); ji->te.prio = cpl->prio; if (! JIAddCplSet_ItemOK(joinGlobals.setJIAddCpl3)) continue; } } else { sprintf(cBuffer, "no object %08x for join from %d", theJoin[i].gid, LC_MsgGetProc(jm)); DDD_PrintError('E', 7300, cBuffer); HARD_EXIT; } } } /* return immediately if no join-objects have been found */ if (nJoinObjs==0) return; /* allocate array of objects, which has been contacted by a join */ joinObjs = (JIPartner *) AllocTmp(sizeof(JIPartner) * nJoinObjs); if (joinObjs==NULL) { DDD_PrintError('E', 7903, STR_NOMEM " in UnpackPhase1Msgs"); HARD_EXIT; } /* set return values */ *p_joinObjs = joinObjs; *p_nJoinObjs = nJoinObjs; /* add one local coupling for each Join */ for(m=0, jo=0; m<nRecvMsgs; m++) { LC_MSGHANDLE jm = theMsgs[m]; TEJoin *theJoin = (TEJoin *) LC_GetPtr(jm, joinGlobals.jointab_id); int nJ = (int) LC_GetTableLen(jm, joinGlobals.jointab_id); int i; for(i=0; i<nJ; i++) { AddCoupling(theJoin[i].hdr, LC_MsgGetProc(jm), theJoin[i].prio); /* send one phase3-JIAddCpl for symmetric connection */ { JIAddCpl *ji = JIAddCplSet_NewItem(joinGlobals.setJIAddCpl3); ji->dest = LC_MsgGetProc(jm); ji->te.gid = OBJ_GID(theJoin[i].hdr); ji->te.proc = me; ji->te.prio = OBJ_PRIO(theJoin[i].hdr); JIAddCplSet_ItemOK(joinGlobals.setJIAddCpl3); } joinObjs[jo].hdr = theJoin[i].hdr; joinObjs[jo].proc = LC_MsgGetProc(jm); jo++; } } /* sort joinObjs-array according to gid */ if (nJoinObjs>1) qsort(joinObjs, nJoinObjs, sizeof(JIPartner), sort_Gid); }
static int PreparePhase1Msgs (JIJoinPtrArray *arrayJoin, JOINMSG1 **theMsgs, size_t *memUsage) { int i, last_i, nMsgs; JIJoin **itemsJ = JIJoinPtrArray_GetData(arrayJoin); int nJ = JIJoinPtrArray_GetSize(arrayJoin); # if DebugJoin<=3 printf("%4d: PreparePhase1Msgs, nJoins=%d\n", me, nJ); fflush(stdout); # endif /* init return parameters */ *theMsgs = NULL; *memUsage = 0; if (nJ==0) /* no messages */ return(0); /* check whether Join objects are really local (without copies) */ /* and set local GID to invalid (will be set to new value lateron) */ for(i=0; i<nJ; i++) { if (ObjHasCpl(itemsJ[i]->hdr)) { sprintf(cBuffer, "cannot join %08x, object already distributed", OBJ_GID(itemsJ[i]->hdr)); DDD_PrintError('E', 7006, cBuffer); HARD_EXIT; } OBJ_GID(itemsJ[i]->hdr) = GID_INVALID; } /* set local GID to new value */ for(i=0; i<nJ; i++) { DDD_GID local_gid = OBJ_GID(itemsJ[i]->hdr); /* check for double Joins with different new_gid */ if (local_gid!=GID_INVALID && local_gid!=itemsJ[i]->new_gid) { sprintf(cBuffer, "several (inconsistent) DDD_JoinObj-commands for local object %08x", local_gid); DDD_PrintError('E', 7007, cBuffer); HARD_EXIT; } OBJ_GID(itemsJ[i]->hdr) = itemsJ[i]->new_gid; } nMsgs = 0; last_i = i = 0; do { JOINMSG1 *jm; size_t bufSize; /* skip until dest-processor is different */ while (i<nJ && (itemsJ[i]->dest == itemsJ[last_i]->dest)) i++; /* create new message */ jm = (JOINMSG1 *) AllocTmp(sizeof(JOINMSG1)); if (jm==NULL) { DDD_PrintError('E', 7900, STR_NOMEM " in PreparePhase1Msgs"); HARD_EXIT; } jm->nJoins = i-last_i; jm->arrayJoin = &(itemsJ[last_i]); jm->dest = itemsJ[last_i]->dest; jm->next = *theMsgs; *theMsgs = jm; nMsgs++; /* create new send message */ jm->msg_h = LC_NewSendMsg(joinGlobals.phase1msg_t, jm->dest); /* init table inside message */ LC_SetTableSize(jm->msg_h, joinGlobals.jointab_id, jm->nJoins); /* prepare message for sending away */ bufSize = LC_MsgPrepareSend(jm->msg_h); *memUsage += bufSize; if (DDD_GetOption(OPT_INFO_JOIN) & JOIN_SHOW_MEMUSAGE) { sprintf(cBuffer, "DDD MESG [%03d]: SHOW_MEM " "send msg phase1 dest=%04d size=%010ld\n", me, jm->dest, (long)bufSize); DDD_PrintLine(cBuffer); } last_i = i; } while (last_i < nJ); return(nMsgs); }