00001
00008 #include <string.h>
00009 #include <stdlib.h>
00010
00011
00012 #include "petable.h"
00013
00014
00015 #define BIGBUFFERSIZE 65536
00016 #define PTPREALLOC 100
00017
00018 struct AllToAllHdr {
00019 char dummy[CmiReservedHeaderSize];
00020 int refno;
00021 comID id;
00022 int size;
00023 int ufield;
00024 int nmsgs;
00025 };
00026
00027
00028
00029
00030
00031 PeTable :: PeTable(int n) {
00032 NumPes=n;
00033 magic=0;
00034 PeList = (PTinfo ***)CmiAlloc(sizeof(PTinfo *)*NumPes);
00035
00036 msgnum=new int[NumPes];
00037 MaxSize=new int[NumPes];
00038 for (int i=0;i<NumPes;i++) {
00039 msgnum[i]=0;
00040 MaxSize[i]=MSGQLEN;
00041 PeList[i]=(PTinfo **)CmiAlloc(sizeof(PTinfo *)*MSGQLEN);
00042 for (int j=0;j<MSGQLEN;j++) PeList[i][j]=0;
00043 }
00044
00045
00046
00047
00048
00049 PTFreeList=NULL;
00050 PTFreeChunks=NULL;
00051 }
00052
00053 PeTable :: ~PeTable() {
00054 int i;
00055 for (i=0;i<NumPes;i++) CmiFree(PeList[i]);
00056 CmiFree(PeList);
00057 delete msgnum;
00058 delete MaxSize;
00059 GarbageCollect();
00060
00061 PTinfo *tmp;
00062 while (PTFreeChunks) {
00063 tmp=PTFreeChunks;
00064 PTFreeChunks=PTNEXTCHUNK(tmp);
00065 CmiFree(tmp);
00066 }
00067
00068
00069 }
00070
00071 void PeTable:: Purge() {
00072 for (int i=0; i<NumPes;i++) {
00073 if (msgnum[i]) {
00074
00075
00076 }
00077 }
00078 GarbageCollect();
00079
00080
00081 }
00082
00083 void PeTable :: ExtractAndDeliverLocalMsgs(int index, Strategy *myStrat) {
00084 int j;
00085 msgstruct m;
00086
00087 ComlibPrintf("%d:Delivering %d local messages\n", CkMyPe(), msgnum[index]);
00088 for (j=msgnum[index]-1;(j>=0);j--) {
00089
00090 m.msgsize=PeList[index][j]->msgsize;
00091 m.msg=PeList[index][j]->msg;
00092
00093 if (--(PeList[index][j]->refCount) <=0) {
00094
00095 myStrat->deliver((char*)m.msg, m.msgsize);
00096 PTFREE(PeList[index][j]);
00097 }
00098 else {
00099 char *dupmsg = (char*)CmiAlloc(m.msgsize);
00100 memcpy(dupmsg, m.msg, m.msgsize);
00101 myStrat->deliver(dupmsg, m.msgsize);
00102
00103 }
00104 PeList[index][j]=NULL;
00105 }
00106 msgnum[index]=j+1;
00107
00108 return;
00109 }
00110
00111
00112 #undef PACK
00113 #undef PACKMSG
00114
00115 #define PACK(type,data) {junk=(char *)&(data); memcpy(t, junk, sizeof(type)); t+=sizeof(type);}
00116 #define PACKMSG(data, size) { memcpy(p+msg_offset, (data), size); msg_offset += size; }
00117
00118
00119
00120
00121
00122
00123 char * PeTable ::ExtractAndPack(comID id, int ufield, int npe,
00124 int *pelist, int *length) {
00125 char *junk;
00126 int nummsgs, offset, num_distinctmsgs;
00127
00128 int tot_msgsize=TotalMsgSize(npe, pelist, &nummsgs, &num_distinctmsgs);
00129
00130 ComlibPrintf("%d In ExtractAndPack %d, %d\n", CmiMyPe(), npe, nummsgs);
00131
00132 if (tot_msgsize ==0) {
00133 *length=0;
00134
00135 ComlibPrintf("Returning NULL\n");
00136 return(NULL);
00137 }
00138
00139 int msg_offset = sizeof(struct AllToAllHdr) + (npe + nummsgs + 1) * sizeof(int);
00140
00141
00142
00143 msg_offset = ALIGN8(msg_offset);
00144
00145 *length = tot_msgsize;
00146 *length += msg_offset;
00147 char *p;
00148 p=(char *)CmiAlloc(*length);
00149
00150 char *t = p + CmiReservedHeaderSize;
00151 int i, j;
00152 if (!p) CmiAbort("Big time problem\n");
00153 magic++;
00154
00155 int refno = id.refno;
00156
00157 PACK(int, refno);
00158 PACK(comID, id);
00159 PACK(int, *length);
00160 PACK(int, ufield);
00161 PACK(int, nummsgs);
00162 PACK(int, npe);
00163
00164 int lesspe=0;
00165 int npacked = 0;
00166 for (i=0;i<npe;i++) {
00167 int index=pelist[i];
00168
00169 if (msgnum[index]<=0) {
00170 lesspe++;
00171
00172 ComlibPrintf("[%d] msgnum[index]<=0 !!!!!\n", CkMyPe());
00173 continue;
00174 }
00175
00176 ComlibPrintf("%d Packing pelist[%d]\n", CkMyPe(), index);
00177 register int newval=-1*pelist[i];
00178 PACK(int, newval);
00179
00180 for (j=0;j<msgnum[index];j++) {
00181 if (PeList[index][j]->magic == magic) {
00182 offset=(PeList[index][j]->offset);
00183 }
00184 else {
00185 npacked ++;
00186
00187
00188 offset=npacked;
00189 PeList[index][j]->magic=magic;
00190 PeList[index][j]->offset=offset;
00191 PTinfo *tempmsg=PeList[index][j];
00192
00193 CmiChunkHeader hdr;
00194 hdr.size = tempmsg->msgsize;
00195 hdr.ref = -1;
00196 PACKMSG(&hdr, sizeof(CmiChunkHeader));
00197 PACKMSG(tempmsg->msg, tempmsg->msgsize);
00198
00199 msg_offset = ALIGN8(msg_offset);
00200 }
00201
00202
00203 PACK(int, offset);
00204
00205 if (--(PeList[index][j]->refCount) <=0) {
00206 CmiFree(PeList[index][j]->msg);
00207
00208 PTFREE(PeList[index][j]);
00209 }
00210 PeList[index][j]=NULL;
00211 }
00212 msgnum[index]=0;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 return(p);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 char * PeTable ::ExtractAndPackAll(comID id, int ufield, int *length) {
00238 int nmsgs = 0;
00239 int i, j;
00240 int index = 0;
00241
00242 ComlibPrintf("[%d] In Extract And Pack All\n", CkMyPe());
00243
00244
00245 magic++;
00246
00247 register int total_msg_size = 0;
00248
00249
00250 for (i=0;i<NumPes;i++) {
00251 index = i;
00252 for (j=msgnum[index]-1; (j>=0); j--) {
00253 if (PeList[index][j]->magic != magic) {
00254 total_msg_size += ALIGN8(PeList[index][j]->msgsize);
00255 total_msg_size += 2 * sizeof(int);
00256 PeList[index][j]->magic=magic;
00257
00258 nmsgs ++;
00259 }
00260 }
00261 }
00262
00263 total_msg_size += ALIGN8(sizeof(AllToAllHdr));
00264
00265 ComlibPrintf("[%d] Message Size %d, nmsgs %d **%d**\n", CkMyPe(), total_msg_size, nmsgs, sizeof(AllToAllHdr));
00266
00267
00268 char *p = (char *) CmiAlloc(total_msg_size * sizeof(char));
00269
00270 ComlibPrintf("After cmialloc\n");
00271
00272
00273 char *t = p;
00274 char *junk = NULL;
00275
00276 int refno = 0;
00277
00278 AllToAllHdr ahdr;
00279 ahdr.refno = refno;
00280 ahdr.id = id;
00281 ahdr.size = *length;
00282 ahdr.ufield = ufield;
00283 ahdr.nmsgs = nmsgs;
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 PACK(AllToAllHdr, ahdr);
00295
00296 int msg_offset = ALIGN8(sizeof(AllToAllHdr));
00297
00298
00299 magic++;
00300 for (i=0;i<NumPes;i++) {
00301 index=i;
00302 int ref = 0;
00303 int size;
00304
00305 for (j=msgnum[index]-1; (j>=0); j--) {
00306
00307 if (PeList[index][j]->magic != magic) {
00308 size = PeList[index][j]->msgsize;
00309 PACKMSG(&size, sizeof(int));
00310 PACKMSG(&ref, sizeof(int));
00311 PeList[index][j]->magic=magic;
00312 PACKMSG(PeList[index][j]->msg, size);
00313
00314 msg_offset = ALIGN8(msg_offset);
00315 }
00316
00317
00318 if (--(PeList[index][j]->refCount) <=0) {
00319 ComlibPrintf("before cmifree \n");
00320 CmiFree(PeList[index][j]->msg);
00321 ComlibPrintf("after cmifree \n");
00322
00323 PTFREE(PeList[index][j]);
00324 }
00325
00326 PeList[index][j] = NULL;
00327 }
00328 msgnum[index] = 0;
00329 }
00330
00331 *length = total_msg_size;
00332 return p;
00333 }
00334
00335 #undef UNPACK
00336 #define UNPACK(type,data) {junk=(char *)&(data); memcpy(junk, t, sizeof(type));t+=sizeof(type);}
00337 #undef UNPACKMSG
00338 #define UNPACKMSG(dest,src, size) { memcpy(dest, src, size); offset += size;}
00339
00340 int PeTable :: UnpackAndInsert(void *in) {
00341 char *junk;
00342 char *t =(char *)in + CmiReservedHeaderSize;
00343 int i, ufield, npe, pe, nummsgs, ptrlistindex=0;
00344 char *msgend, *msgcur;
00345 comID id;
00346 int refno = 0;
00347 int msgsize;
00348
00349 register int offset;
00350
00351 UNPACK(int, refno);
00352 ComlibPrintf("%d UnPackAndInsert\n", CkMyPe());
00353 UNPACK(comID, id);
00354 UNPACK(int, msgsize);
00355 UNPACK(int, ufield);
00356 UNPACK(int, nummsgs);
00357 UNPACK(int, npe);
00358
00359
00360 msgend = (char*)in + msgsize;
00361 msgcur = (char*)in + ALIGN8(sizeof(struct AllToAllHdr) + (npe+nummsgs+1)*sizeof(int));
00362 while (msgcur < msgend) {
00363 CmiChunkHeader *ch = (CmiChunkHeader *)msgcur;
00364
00365 PTinfo *temp;
00366 PTALLOC(temp);
00367 temp->msgsize=ch->size;
00368 temp->msg=(void*)&ch[1];
00369 temp->refCount=0;
00370 temp->magic=0;
00371 temp->offset=0;
00372
00373 ptrvec.insert(++ptrlistindex, temp);
00374
00375
00376 ch->ref = (int)((char*)in - (char*)temp->msg);
00377 msgcur += ALIGN8(ch->size) + sizeof(CmiChunkHeader);
00378 }
00379
00380 pe = -1;
00381
00382 for (i=0; i<nummsgs; ++i) {
00383
00384
00385
00386 UNPACK(int, offset);
00387 if (offset <= 0) {
00388 pe = -1 * offset;
00389 --i;
00390 continue;
00391 }
00392
00393 if (msgnum[pe] >= MaxSize[pe]) {
00394 REALLOC(PeList[pe], MaxSize[pe]);
00395 MaxSize[pe] *= 2;
00396 }
00397 PeList[pe][msgnum[pe]] = ptrvec[offset];
00398 (ptrvec[offset])->refCount++;
00399 msgnum[pe]++;
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 }
00447
00448 REFFIELD(in) = ptrlistindex;
00449 if (ptrlistindex==0) {
00450 REFFIELD(in) = 1;
00451 CmiFree(in);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 ptrvec.removeAll();
00464
00465 return(ufield);
00466 }
00467
00468
00469
00470
00471
00472
00473 int PeTable :: UnpackAndInsertAll(void *in, int npes, int *pelist) {
00474 char *junk;
00475 char *t =(char *)in ;
00476 int i,
00477 ufield,
00478 nmsgs,
00479 refno,
00480 dummy;
00481
00482 comID id;
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 AllToAllHdr ahdr;
00497 UNPACK(AllToAllHdr, ahdr);
00498
00499 if((sizeof(AllToAllHdr) & 7) != 0)
00500 t += 8 - (sizeof(AllToAllHdr) & 7);
00501
00502 refno = ahdr.refno;
00503 id = ahdr.id;
00504 nmsgs = ahdr.nmsgs;
00505 ufield = ahdr.ufield;
00506
00507 ComlibPrintf("[%d] unpack and insert all %d, %d\n", CkMyPe(), ufield, nmsgs);
00508
00509
00510 CmiChunkHeader *chdr= (CmiChunkHeader*)((char*)in - sizeof(CmiChunkHeader));
00511
00512 int *ref;
00513 int size;
00514 char *msg;
00515 for(int count = 0; count < nmsgs; count++){
00516
00517 t += sizeof(CmiChunkHeader);
00518 msg = t;
00519
00520
00521 size = SIZEFIELD(msg);
00522 REFFIELD(msg) = (int)((char *)in - (char *)msg);
00523
00524 t += ALIGN8(size);
00525
00526
00527 chdr->ref++;
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 InsertMsgs(npes, pelist, size, msg);
00543 }
00544
00545 CmiFree(in);
00546 return ufield;
00547 }
00548
00549
00550
00551
00552
00553 PTvectorlist PeTable :: ExtractAndVectorize(comID id, int ufield, int npe, int *pelist) {
00554 char *junk;
00555 int nummsgs = 0;
00556 int offset;
00557 int i, j;
00558
00559 for (i=0; i<npe; ++i) nummsgs += msgnum[pelist[i]];
00560
00561 ComlibPrintf("%d In ExtractAndVectorize %d, %d\n", CmiMyPe(), npe, nummsgs);
00562
00563 if (nummsgs ==0) {
00564 ComlibPrintf("Returning NULL\n");
00565 return(NULL);
00566 }
00567
00568 int headersize = sizeof(struct AllToAllHdr) + (npe + nummsgs + 1) * sizeof(int);
00569
00570
00571
00572 char *p;
00573 p=(char *)CmiAlloc(headersize);
00574
00575 char *t = p + CmiReservedHeaderSize;
00576 if (!p) CmiAbort("Big time problem\n");
00577 magic++;
00578
00579 int refno = id.refno;
00580
00581
00582 PACK(int, refno);
00583 PACK(comID, id);
00584 PACK(int, ufield);
00585 PACK(int, nummsgs);
00586 PACK(int, npe);
00587
00588 int lesspe=0;
00589 int npacked = 0;
00590 for (i=0;i<npe;i++) {
00591 int index=pelist[i];
00592
00593 if (msgnum[index]<=0) {
00594 lesspe++;
00595
00596 ComlibPrintf("[%d] msgnum[index]<=0 !!!!!\n", CkMyPe());
00597 continue;
00598 }
00599
00600 ComlibPrintf("%d Packing pelist[%d]\n", CkMyPe(), index);
00601 register int newval=-1*pelist[i];
00602 PACK(int, newval);
00603
00604 for (j=0;j<msgnum[index];j++) {
00605 if (PeList[index][j]->magic == magic) {
00606 offset=(PeList[index][j]->offset);
00607 }
00608 else {
00609 npacked ++;
00610
00611
00612 offset=npacked;
00613 PeList[index][j]->magic=magic;
00614 PeList[index][j]->offset=offset;
00615 PTinfo *tempmsg=PeList[index][j];
00616
00617 ptrvec.insert(npacked, tempmsg);
00618 }
00619
00620
00621 PACK(int, offset);
00622
00623 --(PeList[index][j]->refCount);
00624
00625
00626
00627
00628
00629
00630
00631 PeList[index][j]=NULL;
00632 }
00633 msgnum[index]=0;
00634 }
00635
00636
00637
00638
00639 PTvectorlist result = (PTvectorlist)CmiAlloc(sizeof(struct ptvectorlist) +
00640 (npacked+1)*2*sizeof(char*) +
00641 2*sizeof(CmiChunkHeader));
00642 result->count = npacked + 1;
00643 result->sizes = (int*)((char*)result + sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
00644 result->msgs = (char**)((char*)result->sizes + (npacked+1)*sizeof(int) + sizeof(CmiChunkHeader));
00645
00646 SIZEFIELD(result->sizes) = (npacked+1)*sizeof(int);
00647 REFFIELD(result->sizes) = - (int)(sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
00648 SIZEFIELD(result->msgs) = (npacked+1)*sizeof(int);
00649 REFFIELD(result->msgs) = - (sizeof(struct ptvectorlist) + (npacked+1)*sizeof(int) + 2*sizeof(CmiChunkHeader));
00650 CmiReference(result);
00651
00652 result->sizes[0] = headersize;
00653 result->msgs[0] = p;
00654 PTinfo *temp;
00655 for (i=1; i<=npacked; ++i) {
00656 temp = ptrvec[i];
00657 result->sizes[i] = temp->msgsize;
00658 result->msgs[i] = (char*)temp->msg;
00659
00660
00661 if (temp->refCount > 0) CmiReference(result->msgs[i]);
00662 else PTFREE(temp);
00663 }
00664
00665 ptrvec.removeAll();
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 return result;
00678 }
00679
00680
00681
00682
00683
00684 PTvectorlist PeTable :: ExtractAndVectorizeAll(comID id, int ufield) {
00685 int nmsgs = 0, i, j;
00686 int index = 0;
00687
00688 ComlibPrintf("[%d] In Extract And Vectorize All\n", CkMyPe());
00689
00690
00691 magic++;
00692
00693
00694
00695
00696 for (i=0;i<NumPes;i++) {
00697 index = i;
00698 for (j=msgnum[index]-1; (j>=0); j--) {
00699 if (PeList[index][j]->magic != magic) {
00700
00701
00702 PeList[index][j]->magic=magic;
00703 ptrvec.insert(nmsgs, PeList[index][j]);
00704 PeList[index][j] = NULL;
00705 nmsgs ++;
00706 }
00707 --(PeList[index][j]->refCount);
00708 }
00709 }
00710
00711
00712
00713 ComlibPrintf("[%d] nmsgs %d **%d**\n", CkMyPe(), nmsgs, sizeof(AllToAllHdr));
00714
00715
00716 AllToAllHdr *ahdr = (AllToAllHdr *) CmiAlloc(sizeof(struct AllToAllHdr));
00717
00718 ComlibPrintf("After cmialloc\n");
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 int refno = 0;
00729
00730 ahdr->refno = refno;
00731 ahdr->id = id;
00732 ahdr->ufield = ufield;
00733 ahdr->nmsgs = nmsgs;
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 PTvectorlist result = (PTvectorlist)CmiAlloc(sizeof(struct ptvectorlist) +
00746 (nmsgs+1)*2*sizeof(char*) +
00747 2*sizeof(CmiChunkHeader));
00748 result->count = nmsgs + 1;
00749 result->sizes = (int*)((char*)result + sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
00750 result->msgs = (char**)((char*)result->sizes + (nmsgs+1)*sizeof(int) + sizeof(CmiChunkHeader));
00751
00752 SIZEFIELD(result->sizes) = (nmsgs+1)*sizeof(int);
00753 REFFIELD(result->sizes) = - (int)(sizeof(struct ptvectorlist) + sizeof(CmiChunkHeader));
00754 SIZEFIELD(result->msgs) = (nmsgs+1)*sizeof(int);
00755 REFFIELD(result->msgs) = - (sizeof(struct ptvectorlist) + (nmsgs+1)*sizeof(int) + 2*sizeof(CmiChunkHeader));
00756 CmiReference(result);
00757
00758 result->sizes[0] = sizeof(ahdr);
00759 result->msgs[0] = (char*)ahdr;
00760 PTinfo *temp;
00761 for (i=1; i<nmsgs; ++i) {
00762 temp = ptrvec[i];
00763 result->sizes[i] = temp->msgsize;
00764 result->msgs[i] = (char*)temp->msg;
00765
00766
00767 if (temp->refCount > 0) CmiReference(result->msgs[i]);
00768 else PTFREE(temp);
00769 }
00770
00771 ptrvec.removeAll();
00772
00773 return result;
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 }
00817
00818 void PeTable :: GarbageCollect() {
00819 }
00820