File indexing completed on 2025-12-21 17:51:06 UTC
view on githubraw file Latest commit feb7fa5d on 2025-11-21 15:45:20 UTC
feb7fa5d1e dngo*0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
b4daa24319 Shre*0013 #include <stdlib.h>
0014 #include <stdio.h>
0015 #include <string.h>
feb7fa5d1e dngo*0016 #include <sys/time.h>
0017 #include <time.h>
0018 #include <stdint.h>
0019 #include <inttypes.h>
b4daa24319 Shre*0020
feb7fa5d1e dngo*0021 #include "adStack.h"
b4daa24319 Shre*0022 #include "adComplex.h"
0023
feb7fa5d1e dngo*0024
0025
0026
0027
b4daa24319 Shre*0028
feb7fa5d1e dngo*0029
0030
0031
0032
0033
0034
0035
b4daa24319 Shre*0036
feb7fa5d1e dngo*0037
0038
b4daa24319 Shre*0039
feb7fa5d1e dngo*0040
0041
b4daa24319 Shre*0042
feb7fa5d1e dngo*0043
0044
0045
0046
0047
0048 #ifndef ADSTACK_BLOCK_SIZE
0049
0050
0051
0052
0053 #define ADSTACK_BLOCK_SIZE 1048576
0054 #endif
0055
0056 #ifndef ADSTACK_MAX_SPACES
0057
0058
0059 #define ADSTACK_MAX_SPACES 8000
0060 #endif
0061
0062
0063
0064 #ifdef ADSTACK_PREFETCH
0065
0066 #include <pthread.h>
0067
0068
0069
0070
0071
0072 #define FETCHAHEAD 10
0073
0074 pthread_t fileStorageThread ;
0075 pthread_mutex_t fileStorageMutex;
0076 pthread_cond_t enqueuedStorageCV, doneStoreOrRestoreCV ;
0077
0078 #endif
0079
0080 #ifdef ADSTACK_TRACE
0081
0082 static int tracedId = -1 ;
0083 #endif
b4daa24319 Shre*0084
feb7fa5d1e dngo*0085 typedef enum {INUSE, STORED} CONTENTS_STATE ;
0086 typedef enum {NOACTION, STORE, RESTORE} ACTION ;
0087
0088 char* stateNames[] = {"U", "S"};
0089
0090
0091
0092 typedef struct {
0093 unsigned int rank ;
0094 CONTENTS_STATE state ;
0095 char contents[ADSTACK_BLOCK_SIZE] ;
0096 #ifdef ADSTACK_TRACE
0097 int id ;
0098 #endif
0099 } BlockContents ;
0100
0101
0102
0103
b4daa24319 Shre*0104 typedef struct _DoubleChainedBlock{
feb7fa5d1e dngo*0105 unsigned int rank ;
b4daa24319 Shre*0106 struct _DoubleChainedBlock *prev ;
0107 struct _DoubleChainedBlock *next ;
feb7fa5d1e dngo*0108 BlockContents* toContents ;
b4daa24319 Shre*0109 } DoubleChainedBlock ;
0110
feb7fa5d1e dngo*0111
0112
0113 char tapStackFileName[14] ;
0114
0115
0116
0117
0118 ACTION fileActionBeingDone = NOACTION ;
0119 BlockContents *spaceBeingDone = NULL ;
0120 int rankBeingDone = -1 ;
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 static DoubleChainedBlock *curStack = NULL ;
0132 static char* tapblock = NULL ;
0133 static int tappos = ADSTACK_BLOCK_SIZE ;
0134
0135
0136
0137 static BlockContents* allBlockContents[ADSTACK_MAX_SPACES] ;
0138
0139
0140
0141
b4daa24319 Shre*0142 typedef struct _RepetitionLevel {
0143 int active ;
feb7fa5d1e dngo*0144
b4daa24319 Shre*0145 DoubleChainedBlock* resumePointBlock ;
0146 int resumePoint ;
feb7fa5d1e dngo*0147
b4daa24319 Shre*0148 DoubleChainedBlock* freePushBlock ;
0149 int freePush ;
feb7fa5d1e dngo*0150
0151 DoubleChainedBlock* backPopBlock ;
0152 int hasBackPop ;
0153 int backPop ;
b4daa24319 Shre*0154 unsigned int storedadbitbuf ;
0155 int storedadbitibuf ;
0156 struct _RepetitionLevel *previous ;
0157 } RepetitionLevel ;
0158
feb7fa5d1e dngo*0159
0160
b4daa24319 Shre*0161 RepetitionLevel *topRepetitionPoint = NULL ;
0162
feb7fa5d1e dngo*0163
0164
0165
b4daa24319 Shre*0166 static unsigned int adbitbuf = 0 ;
0167 static int adbitibuf = 0 ;
0168
0169
feb7fa5d1e dngo*0170 static u_int64_t pushPopTraffic = 0 ;
b4daa24319 Shre*0171
0172
feb7fa5d1e dngo*0173 static u_int64_t maxBlocks = 0 ;
b4daa24319 Shre*0174
0175
0176
0177
0178
0179 #pragma omp threadprivate(tappos, tapblock, curStack, adbitbuf, adbitibuf, topRepetitionPoint)
0180
feb7fa5d1e dngo*0181
0182 void showLocation(DoubleChainedBlock *locBlock, int loc) ;
0183 void dumpContents(BlockContents *space) ;
0184 void dumpStack(DoubleChainedBlock *st) ;
0185 void dumpRepetitionLevels() ;
b4daa24319 Shre*0186
feb7fa5d1e dngo*0187 char* pushBlock() ;
0188 char* popBlock() ;
0189 void removeStorageFile(int blockRank) ;
0190 void storeInFile(BlockContents* blockContents) ;
0191 void restoreFromFile(BlockContents* blockContents) ;
b4daa24319 Shre*0192
feb7fa5d1e dngo*0193 #ifdef ADSTACK_PREFETCH
b4daa24319 Shre*0194
feb7fa5d1e dngo*0195
0196
0197 void dumpFileActionQueue() ;
0198 #endif
0199
0200
0201 typedef struct _FileActionCell {
0202 struct _FileActionCell *next ;
0203 int restoredRank ;
0204 ACTION action ;
0205 BlockContents *space ;
0206 } FileActionCell ;
0207
0208
0209 FileActionCell *fileActionQueueHead = NULL;
0210 FileActionCell *fileActionQueueTail = NULL;
0211
0212 #ifdef ADSTACK_PREFETCH
0213
0214 int enqueued(BlockContents *space) {
0215 int found = 0 ;
0216 FileActionCell *curCell = fileActionQueueHead ;
0217 while (!found && curCell) {
0218 found = (curCell->space==space) ;
0219 curCell = curCell->next ;
0220 }
0221 return found ;
0222 }
0223
0224
0225 void addTailFileAction(BlockContents *space, ACTION action, int restoredRank) {
0226 FileActionCell *newCell = (FileActionCell*)malloc(sizeof(FileActionCell)) ;
0227 newCell->next = NULL ;
0228 newCell->action = action ;
0229 newCell->restoredRank = restoredRank ;
0230 newCell->space = space ;
0231 if (fileActionQueueHead==NULL) {
0232 fileActionQueueHead = newCell ;
0233 fileActionQueueTail = newCell ;
0234 } else {
0235 fileActionQueueTail->next = newCell ;
0236 fileActionQueueTail = newCell ;
0237 }
0238 }
0239
0240
0241 BlockContents *popHeadFileAction() {
0242 BlockContents *result = fileActionQueueHead->space ;
0243 if (fileActionQueueHead==fileActionQueueTail) {
0244 free(fileActionQueueHead) ;
0245 fileActionQueueHead = NULL ;
0246 fileActionQueueTail = NULL ;
0247 } else {
0248 FileActionCell *tofree = fileActionQueueHead ;
0249 fileActionQueueHead = tofree->next ;
0250 free(tofree) ;
0251 }
0252 return result ;
0253 }
0254
0255
0256 void dequeueFileAction(FileActionCell *cell) {
0257 FileActionCell **toheadcell = &(fileActionQueueHead) ;
0258 FileActionCell *lastCellSeen = NULL ;
0259 while (*toheadcell) {
0260 if (*toheadcell==cell) {
0261 *toheadcell = cell->next ;
0262 free(cell) ;
0263 if (!*toheadcell) {
0264 fileActionQueueTail = lastCellSeen ;
0265 }
0266 } else {
0267 lastCellSeen = *toheadcell ;
0268 toheadcell = &((*toheadcell)->next) ;
0269 }
0270 }
0271 }
0272
0273
0274 void emptyFileActionQueue() {
0275 while (fileActionQueueHead) {
0276 FileActionCell *tofree = fileActionQueueHead ;
0277 #ifdef ADSTACK_TRACE
0278 printf(" Forget %s (%c: %02i %s)\n",
0279 (tofree->action==STORE ? "store" : "restore"),
0280 'a'+tofree->space->id,
0281 tofree->space->rank,
0282 stateNames[tofree->space->state]) ;
0283 #endif
0284 fileActionQueueHead = tofree->next ;
0285 free(tofree) ;
0286 }
0287 fileActionQueueTail = NULL ;
0288 }
0289
0290
0291 FileActionCell *alreadyEnqueuedRestore(BlockContents *space) {
0292 FileActionCell *found = NULL ;
0293 FileActionCell *curCell = fileActionQueueHead ;
0294 while (!found && curCell) {
0295 if (curCell->action==RESTORE
0296 && curCell->space==space) {
0297 found = curCell ;
0298 }
0299 curCell = curCell->next ;
0300 }
0301 return found ;
0302 }
0303
0304
0305
0306
0307
0308 static int goingForward = 1 ;
0309
0310
0311 void enqueueFileAction(BlockContents* space, ACTION action, int restoredRank) {
0312 struct timespec ts ;
0313 #ifdef ADSTACK_TRACE
0314 if (tracedId==-1 || tracedId==space->id) {
0315 clock_gettime(CLOCK_REALTIME, &ts);
0316 if (action==STORE) {
0317 printf("t%09i Enqueue store (%c: %02i %s)\n", ts.tv_nsec,
0318 'a'+space->id,
0319 space->rank,
0320 stateNames[space->state]) ;
0321 } else if (action==RESTORE) {
0322 printf("t%09i Enqueue restore %02i into (%c: %02i %s)\n", ts.tv_nsec,
0323 restoredRank,
0324 'a'+space->id,
0325 space->rank,
0326 stateNames[space->state]) ;
0327 }
0328 }
0329 #endif
0330 addTailFileAction(space, action, restoredRank) ;
0331 #ifdef ADSTACK_TRACE
0332 clock_gettime(CLOCK_REALTIME, &ts);
0333 printf("t%09i Send signal enqueuedStorageCV\n", ts.tv_nsec) ;
0334 #endif
0335 pthread_cond_signal(&enqueuedStorageCV) ;
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 void preStoreBlock(BlockContents *future, int storedRank) {
0351 #ifdef ADSTACK_TRACE
0352 if (tracedId==-1 || tracedId==future->id) {
0353 struct timespec ts ;
0354 clock_gettime(CLOCK_REALTIME, &ts);
0355 printf("t%09i preStoreBlock (%c: %02i %s)\n", ts.tv_nsec,
0356 'a'+future->id, future->rank, stateNames[future->state]) ;
0357 dumpRepetitionLevels() ;
0358 }
0359 #endif
0360
0361 if (future->state==INUSE) {
0362 if (spaceBeingDone==future || enqueued(future)) {
0363
0364 } else {
0365 enqueueFileAction(future, STORE, storedRank) ;
0366 }
0367 }
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 void preRestoreBlock(BlockContents *future, int restoredRank) {
0387 #ifdef ADSTACK_TRACE
0388 if (tracedId==-1 || tracedId==future->id) {
0389 struct timespec ts;
0390 clock_gettime(CLOCK_REALTIME, &ts);
0391 printf("t%09i preRestoreBlock %02i INTO (%c: %02i %s)\n", ts.tv_nsec,
0392 restoredRank, 'a'+future->id, future->rank, stateNames[future->state]) ;
0393 dumpRepetitionLevels() ;
0394 }
0395 #endif
0396 FileActionCell *enqueuedRestore ;
0397 if (fileActionBeingDone==RESTORE && spaceBeingDone==future) {
0398 if (rankBeingDone!=restoredRank) {
0399 enqueueFileAction(future, RESTORE, restoredRank) ;
0400 }
0401 } else if ((enqueuedRestore = alreadyEnqueuedRestore(future)) != NULL) {
0402 enqueuedRestore->restoredRank = restoredRank ;
0403 if (future->rank==restoredRank) {
0404 dequeueFileAction(enqueuedRestore) ;
0405 }
0406 } else if ((fileActionBeingDone==STORE && spaceBeingDone==future)
0407 || enqueued(future)) {
0408 if (future->rank!=restoredRank) {
0409 enqueueFileAction(future, RESTORE, restoredRank) ;
0410 }
0411 } else {
0412 if (future->rank!=restoredRank) {
0413 if (future->state==INUSE) {
0414 enqueueFileAction(future, STORE, 0) ;
0415 }
0416 enqueueFileAction(future, RESTORE, restoredRank) ;
0417 }
0418 }
0419 }
0420
0421
0422
0423
0424
0425 void preStore() {
0426 if (!goingForward) {
0427 emptyFileActionQueue() ;
0428 goingForward = 1 ;
0429 }
0430 preStoreBlock(curStack->toContents, curStack->rank) ;
0431 int curIndex = (curStack->rank - 1)%ADSTACK_MAX_SPACES ;
0432 for (int i=1 ; i<=FETCHAHEAD ; ++i) {
0433 BlockContents *future = allBlockContents[(curIndex+i<ADSTACK_MAX_SPACES ? curIndex+i : curIndex+i-ADSTACK_MAX_SPACES)] ;
0434 if (future) {
0435 preStoreBlock(future, curStack->rank + i) ;
0436 }
0437 }
0438 }
0439
0440
0441
0442
0443
0444 void preStoreAtFreePush() {
0445 if (!goingForward) {
0446 emptyFileActionQueue() ;
0447 goingForward = 1 ;
0448 }
0449
0450
0451
0452 preRestoreBlock(curStack->toContents, curStack->rank) ;
0453 int curIndex = (curStack->rank - 1)%ADSTACK_MAX_SPACES ;
0454 for (int i=1 ; i<=FETCHAHEAD ; ++i) {
0455 BlockContents *future = allBlockContents[(curIndex+i<ADSTACK_MAX_SPACES ? curIndex+i : curIndex+i-ADSTACK_MAX_SPACES)] ;
0456 if (future) {
0457 preStoreBlock(future, curStack->rank + i) ;
0458 }
0459 }
0460 }
0461
0462
0463
0464
0465 void preRestore() {
0466 if (goingForward) {
0467 emptyFileActionQueue() ;
0468 goingForward = 0 ;
0469 }
0470 preRestoreBlock(curStack->toContents, curStack->rank) ;
0471 int curIndex = (curStack->rank - 1)%ADSTACK_MAX_SPACES ;
0472 for (int i=0 ; i<=FETCHAHEAD && i<curStack->rank ; ++i) {
0473 BlockContents *future = allBlockContents[(curIndex-i>=0 ? curIndex-i : curIndex-i+ADSTACK_MAX_SPACES)] ;
0474 preRestoreBlock(future, curStack->rank - i) ;
0475 }
0476 }
b4daa24319 Shre*0477
feb7fa5d1e dngo*0478
0479
0480
0481 void waitForward() {
0482 BlockContents *space = curStack->toContents ;
0483
0484
0485 struct timespec ts;
0486 while (spaceBeingDone==space
0487 || space->state==INUSE
0488 || enqueued(space)) {
0489 #ifdef ADSTACK_TRACE
0490 clock_gettime(CLOCK_REALTIME, &ts);
0491 printf("t%09i Waiting forward for [%02i (%c: %02i %s)] %c%c%c\n", ts.tv_nsec,
0492 curStack->rank, 'a'+space->id, space->rank, stateNames[space->state],
0493 (spaceBeingDone==space ? 't' : 'f'),
0494 (space->state==INUSE ? 't' : 'f'),
0495 (enqueued(space) ? 't' : 'f')) ;
0496 #endif
0497 int rt = 0 ;
0498
0499
0500
0501 pthread_cond_wait(&doneStoreOrRestoreCV, &fileStorageMutex) ;
0502 #ifdef ADSTACK_TRACE
0503 clock_gettime(CLOCK_REALTIME, &ts);
0504 printf("t%09i Wait forward %s\n", ts.tv_nsec, (rt ? "timed out" : "woke up")) ;
0505 #endif
0506 }
0507 #ifdef ADSTACK_TRACE
0508 clock_gettime(CLOCK_REALTIME, &ts);
0509 printf("t%09i Done waiting forward [%02i (%c: %02i %s)]\n", ts.tv_nsec,
0510 curStack->rank, 'a'+space->id, space->rank, stateNames[space->state]) ;
0511 #endif
0512 }
0513
0514
0515
0516
0517 void waitBackward() {
0518 BlockContents *space = curStack->toContents ;
0519 struct timespec ts;
0520
0521
0522
0523 while (spaceBeingDone==space
0524 || space->rank!=curStack->rank
0525 || enqueued(space)) {
0526 #ifdef ADSTACK_TRACE
0527 clock_gettime(CLOCK_REALTIME, &ts);
0528 printf("t%09i Waiting backward for %02i (%c: %02i %s) %c%c%c\n", ts.tv_nsec,
0529 curStack->rank, 'a'+space->id, space->rank, stateNames[space->state],
0530 (spaceBeingDone==space ? 't' : 'f'),
0531 (space->rank!=curStack->rank ? 't' : 'f'),
0532 (enqueued(space) ? 't' : 'f')) ;
0533 #endif
0534 int rt = 0 ;
0535
0536
0537
0538
0539 pthread_cond_wait(&doneStoreOrRestoreCV, &fileStorageMutex) ;
0540 #ifdef ADSTACK_TRACE
0541 clock_gettime(CLOCK_REALTIME, &ts);
0542 printf("t%09i Wait backward %s for %02i (%c: %02i %s)\n", ts.tv_nsec,
0543 (rt ? "timed out" : "woke up"),
0544 curStack->rank, 'a'+space->id, space->rank, stateNames[space->state]) ;
0545 #endif
0546 }
0547 #ifdef ADSTACK_TRACE
0548 clock_gettime(CLOCK_REALTIME, &ts);
0549 printf("t%09i Done waiting backward [%02i (%c: %02i %s)]\n", ts.tv_nsec,
0550 curStack->rank, 'a'+space->id, space->rank, stateNames[space->state]) ;
0551 #endif
0552 }
0553
0554 #else
0555
0556
0557
0558 int enqueued(BlockContents *space) {return 0 ;}
0559
0560 void checkForward() {
0561
0562 BlockContents *space = curStack->toContents ;
0563 if (space->state==INUSE) {
0564 #ifdef ADSTACK_TRACE
0565 if (tracedId==-1 || tracedId==space->id) {
0566 printf(" store (%c: %02i %s) into file tapStack%05i\n", 'a'+space->id,
0567 space->rank, stateNames[space->state], space->rank) ;
0568 }
0569 #endif
0570 storeInFile(space) ;
0571 space->state = STORED ;
0572 }
0573 }
0574
0575 void checkBackward() {
0576
0577 BlockContents *space = curStack->toContents ;
0578 if (space->rank!=curStack->rank) {
0579 if (space->state==INUSE) {
0580 #ifdef ADSTACK_TRACE
0581 if (tracedId==-1 || tracedId==space->id) {
0582 printf(" store (%c: %02i %s) into file tapStack%05i\n", 'a'+space->id,
0583 space->rank, stateNames[space->state], space->rank) ;
0584 }
0585 #endif
0586 storeInFile(space) ;
0587 }
0588 space->rank = curStack->rank ;
0589 #ifdef ADSTACK_TRACE
0590 if (tracedId==-1 || tracedId==space->id) {
0591 printf(" restore (%c: %02i %s) from file tapStack%05i\n", 'a'+space->id,
0592 space->rank, stateNames[space->state], space->rank) ;
0593 }
0594 #endif
0595 restoreFromFile(space) ;
0596 space->state = STORED ;
0597 }
0598 }
0599
0600 #endif
0601
0602
0603
0604
b4daa24319 Shre*0605 void setBackPopToCurrentLocation(RepetitionLevel *repetitionLevel) {
0606 repetitionLevel->hasBackPop = 1 ;
0607 repetitionLevel->backPopBlock = curStack ;
0608 repetitionLevel->backPop = tappos ;
0609 }
0610
feb7fa5d1e dngo*0611
b4daa24319 Shre*0612 void setCurrentLocationToBackPop(RepetitionLevel *repetitionLevel) {
0613 curStack = repetitionLevel->backPopBlock ;
feb7fa5d1e dngo*0614 #ifdef ADSTACK_PREFETCH
0615
0616 pthread_mutex_lock(&fileStorageMutex) ;
0617 emptyFileActionQueue() ;
0618 goingForward = 0 ;
0619 preRestore() ;
0620 waitBackward() ;
0621 curStack->toContents->rank = curStack->rank ;
0622 pthread_mutex_unlock(&fileStorageMutex) ;
0623
0624 #else
0625 checkBackward() ;
0626 curStack->toContents->rank = curStack->rank ;
0627 #endif
0628 #ifdef ADSTACK_TRACE
0629 struct timespec ts;
0630 clock_gettime(CLOCK_REALTIME, &ts);
0631 printf("t%09i %02i <= BackPop\n", ts.tv_nsec, curStack->rank) ;
0632 #endif
0633 tapblock = curStack->toContents->contents ;
b4daa24319 Shre*0634 tappos = repetitionLevel->backPop ;
0635 }
0636
feb7fa5d1e dngo*0637
b4daa24319 Shre*0638 void setResumePointToCurrentLocation(RepetitionLevel *repetitionLevel) {
0639 repetitionLevel->resumePointBlock = curStack ;
0640 repetitionLevel->resumePoint = tappos ;
0641 }
0642
feb7fa5d1e dngo*0643
b4daa24319 Shre*0644 void setCurrentLocationToResumePoint(RepetitionLevel *repetitionLevel) {
0645 curStack = repetitionLevel->resumePointBlock ;
feb7fa5d1e dngo*0646 #ifdef ADSTACK_PREFETCH
0647
0648 pthread_mutex_lock(&fileStorageMutex) ;
0649 emptyFileActionQueue() ;
0650 goingForward = 0 ;
0651 preRestore() ;
0652 waitBackward() ;
0653 curStack->toContents->rank = curStack->rank ;
0654 pthread_mutex_unlock(&fileStorageMutex) ;
0655
0656 #else
0657 checkBackward() ;
0658 curStack->toContents->rank = curStack->rank ;
0659 #endif
0660 #ifdef ADSTACK_TRACE
0661 struct timespec ts;
0662 clock_gettime(CLOCK_REALTIME, &ts);
0663 printf("t%09i %02i <= Repeat\n", ts.tv_nsec, curStack->rank) ;
0664 #endif
0665 tapblock = curStack->toContents->contents ;
b4daa24319 Shre*0666 tappos = repetitionLevel->resumePoint ;
0667 }
0668
feb7fa5d1e dngo*0669
b4daa24319 Shre*0670 void setFreePushToCurrentLocation(RepetitionLevel *repetitionLevel) {
0671 repetitionLevel->freePushBlock = curStack ;
0672 repetitionLevel->freePush = tappos ;
0673 }
0674
feb7fa5d1e dngo*0675
b4daa24319 Shre*0676 void setCurrentLocationToFreePush(RepetitionLevel *repetitionLevel) {
0677 curStack = repetitionLevel->freePushBlock ;
feb7fa5d1e dngo*0678 #ifdef ADSTACK_PREFETCH
0679
0680 pthread_mutex_lock(&fileStorageMutex) ;
0681 emptyFileActionQueue() ;
0682 goingForward = 1 ;
0683 preStoreAtFreePush() ;
0684 waitBackward() ;
0685 curStack->toContents->rank = curStack->rank ;
0686 curStack->toContents->state = INUSE ;
0687 pthread_mutex_unlock(&fileStorageMutex) ;
0688
0689 #else
0690 checkBackward() ;
0691 curStack->toContents->rank = curStack->rank ;
0692 curStack->toContents->state = INUSE ;
0693 #endif
0694 #ifdef ADSTACK_TRACE
0695 struct timespec ts;
0696 clock_gettime(CLOCK_REALTIME, &ts);
0697 printf("t%09i FreePush => %02i\n", ts.tv_nsec, curStack->rank) ;
0698 #endif
0699 tapblock = curStack->toContents->contents ;
b4daa24319 Shre*0700 tappos = repetitionLevel->freePush ;
0701 }
0702
0703
feb7fa5d1e dngo*0704
b4daa24319 Shre*0705 int currentLocationStrictBelowFreePush(RepetitionLevel *repetitionLevel) {
feb7fa5d1e dngo*0706
0707
0708 int curL1 = curStack->rank ;
0709 int curL2 = tappos ;
0710 int fpL1 = repetitionLevel->freePushBlock->rank ;
0711 int fpL2 = repetitionLevel->freePush ;
0712 if (curL2==ADSTACK_BLOCK_SIZE) {++curL1 ; curL2=0 ;}
0713 if (fpL2==ADSTACK_BLOCK_SIZE) {++fpL1 ; fpL2=0 ;}
0714 return (curL1<fpL1 || (curL1==fpL1 && curL2<fpL2)) ;
b4daa24319 Shre*0715 }
0716
0717
feb7fa5d1e dngo*0718
b4daa24319 Shre*0719 int currentLocationEqualsFreePush(RepetitionLevel *repetitionLevel) {
feb7fa5d1e dngo*0720
0721
0722 int curL1 = curStack->rank ;
0723 int curL2 = tappos ;
0724 int fpL1 = repetitionLevel->freePushBlock->rank ;
0725 int fpL2 = repetitionLevel->freePush ;
0726 if (curL2==ADSTACK_BLOCK_SIZE) {++curL1 ; curL2=0 ;}
0727 if (fpL2==ADSTACK_BLOCK_SIZE) {++fpL1 ; fpL2=0 ;}
0728 return (curL1==fpL1 && curL2==fpL2) ;
b4daa24319 Shre*0729 }
0730
feb7fa5d1e dngo*0731
0732
0733 int currentLocationEqualsBackPop(RepetitionLevel *repetitionLevel) {
0734
0735
0736 int curL1 = curStack->rank ;
0737 int curL2 = tappos ;
0738 int bpL1 = repetitionLevel->backPopBlock->rank ;
0739 int bpL2 = repetitionLevel->backPop ;
0740 if (curL2==ADSTACK_BLOCK_SIZE) {++curL1 ; curL2=0 ;}
0741 if (bpL2==ADSTACK_BLOCK_SIZE) {++bpL1 ; bpL2=0 ;}
0742 return (curL1==bpL1 && curL2==bpL2) ;
b4daa24319 Shre*0743 }
0744
0745
feb7fa5d1e dngo*0746
0747
b4daa24319 Shre*0748 void checkPushInReadOnly() {
0749 RepetitionLevel *topActive = topRepetitionPoint ;
0750 while (topActive && !topActive->active) {
0751 topActive = topActive->previous ;
0752 }
feb7fa5d1e dngo*0753 if (topActive) {
0754 if(currentLocationStrictBelowFreePush(topActive)) {
0755 setBackPopToCurrentLocation(topActive) ;
0756 setCurrentLocationToFreePush(topActive) ;
0757 #ifdef ADSTACK_TRACE
b4daa24319 Shre*0758 printf("BEFORE PUSH AT ") ;
0759 showLocation(topRepetitionPoint->backPopBlock, topRepetitionPoint->backPop) ;
0760 printf(" WITH REPETITION LEVELS:\n") ;
feb7fa5d1e dngo*0761 dumpRepetitionLevels() ;
b4daa24319 Shre*0762 printf(" MOVE TO FREE PUSH LOCATION ") ;
0763 showLocation(topRepetitionPoint->freePushBlock, topRepetitionPoint->freePush) ;
0764 printf("\n") ;
feb7fa5d1e dngo*0765 #endif
0766 } else if (currentLocationEqualsFreePush(topActive)) {
0767
0768 setCurrentLocationToFreePush(topActive) ;
0769 #ifdef ADSTACK_TRACE
0770 printf("BEFORE PUSH 2 AT ") ;
0771 showLocation(topRepetitionPoint->backPopBlock, topRepetitionPoint->backPop) ;
0772 printf(" WITH REPETITION LEVELS:\n") ;
0773 dumpRepetitionLevels() ;
0774 printf(" MOVE TO FREE PUSH LOCATION ") ;
0775 showLocation(topRepetitionPoint->freePushBlock, topRepetitionPoint->freePush) ;
0776 printf("\n") ;
0777 #endif
b4daa24319 Shre*0778 }
0779 }
0780 }
0781
0782
feb7fa5d1e dngo*0783
0784
b4daa24319 Shre*0785 void checkPopToReadOnly() {
0786 RepetitionLevel *repetitionPoint = topRepetitionPoint ;
feb7fa5d1e dngo*0787 #ifdef ADSTACK_TRACE
0788 RepetitionLevel *activeRepetitionPoint = topRepetitionPoint ;
0789 while (activeRepetitionPoint && !activeRepetitionPoint->active) {
0790 activeRepetitionPoint = activeRepetitionPoint->previous ;
0791 }
0792 if (activeRepetitionPoint && activeRepetitionPoint->hasBackPop
0793 && currentLocationEqualsFreePush(activeRepetitionPoint)) {
b4daa24319 Shre*0794 printf("AFTER POP, LOCATION WAS ") ;
0795 showLocation(curStack, tappos) ;
0796 printf(" WITH REPETITION LEVELS:\n") ;
feb7fa5d1e dngo*0797 dumpRepetitionLevels() ;
b4daa24319 Shre*0798 }
feb7fa5d1e dngo*0799 #endif
b4daa24319 Shre*0800 int canEraseInactive = 1 ;
0801 int canRemoveBackPop = 1 ;
0802 do {
0803 RepetitionLevel *oldCell = repetitionPoint ;
feb7fa5d1e dngo*0804 if (oldCell->hasBackPop && oldCell->active) {
0805 if (currentLocationEqualsFreePush(oldCell)) {
0806 setCurrentLocationToBackPop(oldCell) ;
0807 #ifdef ADSTACK_TRACE
0808 printf(" MOVED TO BACK POP LOCATION:") ;
0809 showLocation(curStack, tappos) ;
0810 printf("\n") ;
0811 #endif
0812 if (canRemoveBackPop) oldCell->hasBackPop = 0 ;
0813 } else if (currentLocationEqualsBackPop(oldCell)) {
0814 if (canRemoveBackPop) oldCell->hasBackPop = 0 ;
0815 }
b4daa24319 Shre*0816 }
0817 repetitionPoint = oldCell->previous ;
0818 if (!oldCell->active && canEraseInactive) {
0819 free(oldCell) ;
0820 topRepetitionPoint = repetitionPoint ;
0821 } else {
0822 canEraseInactive = 0 ;
0823 canRemoveBackPop = 0 ;
0824 }
0825 } while (repetitionPoint) ;
0826 }
0827
0828
0829
0830
feb7fa5d1e dngo*0831
0832
b4daa24319 Shre*0833 void adStack_startRepeat() {
feb7fa5d1e dngo*0834 #ifdef ADSTACK_TRACE
0835 printf("BEFORE START REPEAT AT ") ;
0836 showLocation(curStack, tappos) ;
0837 printf("\n") ;
0838 dumpRepetitionLevels() ;
0839 dumpStack(curStack) ; printf("\n") ;
0840 #endif
b4daa24319 Shre*0841
0842 RepetitionLevel *newRepetitionLevel = (RepetitionLevel *)malloc(sizeof(RepetitionLevel)) ;
feb7fa5d1e dngo*0843 if (!newRepetitionLevel) {
0844 printf("Out of memory while creating a RepetitionLevel.\n") ;
0845 exit(0) ;
0846 }
b4daa24319 Shre*0847 newRepetitionLevel->previous = topRepetitionPoint ;
0848 newRepetitionLevel->hasBackPop = 0 ;
0849 newRepetitionLevel->active = 1 ;
feb7fa5d1e dngo*0850 newRepetitionLevel->backPopBlock = NULL ;
0851 newRepetitionLevel->backPop = 0 ;
0852 newRepetitionLevel->resumePointBlock = NULL ;
0853 newRepetitionLevel->resumePoint = 0 ;
0854 newRepetitionLevel->freePushBlock = NULL ;
0855 newRepetitionLevel->freePush = 0 ;
b4daa24319 Shre*0856
0857 newRepetitionLevel->storedadbitbuf = adbitbuf ;
0858 newRepetitionLevel->storedadbitibuf = adbitibuf ;
0859
0860 if (curStack==NULL) {
0861 tapblock = pushBlock() ;
0862 tappos = 0 ;
0863 }
0864
0865 setResumePointToCurrentLocation(newRepetitionLevel) ;
0866
0867
0868
0869 if (topRepetitionPoint && currentLocationStrictBelowFreePush(topRepetitionPoint)) {
0870 newRepetitionLevel->freePushBlock = topRepetitionPoint->freePushBlock ;
0871 newRepetitionLevel->freePush = topRepetitionPoint->freePush ;
0872 } else {
0873 setFreePushToCurrentLocation(newRepetitionLevel) ;
0874 }
0875
0876 topRepetitionPoint = newRepetitionLevel ;
feb7fa5d1e dngo*0877 #ifdef ADSTACK_TRACE
0878 printf(">AFTER START REPEAT AT:") ;
0879 showLocation(curStack, tappos) ;
0880 printf("\n") ;
0881 dumpRepetitionLevels() ;
0882 dumpStack(curStack) ; printf("\n") ;
0883 #endif
b4daa24319 Shre*0884 }
0885
0886
0887
feb7fa5d1e dngo*0888
0889
b4daa24319 Shre*0890 void adStack_resetRepeat() {
feb7fa5d1e dngo*0891 #ifdef ADSTACK_TRACE
0892 printf("BEFORE RESET REPEAT AT ") ;
0893 showLocation(curStack, tappos) ;
0894 printf("\n") ;
0895 dumpRepetitionLevels() ;
0896 dumpStack(curStack) ; printf("\n") ;
0897 #endif
b4daa24319 Shre*0898
0899 while (topRepetitionPoint && !topRepetitionPoint->active) {
0900 RepetitionLevel *oldTop = topRepetitionPoint ;
0901 topRepetitionPoint = topRepetitionPoint->previous ;
0902 free(oldTop) ;
0903 }
0904
0905 setCurrentLocationToResumePoint(topRepetitionPoint) ;
0906
0907 adbitbuf = topRepetitionPoint->storedadbitbuf ;
0908 adbitibuf = topRepetitionPoint->storedadbitibuf ;
feb7fa5d1e dngo*0909 #ifdef ADSTACK_TRACE
0910 printf(">AFTER RESET REPEAT AT ") ;
0911 showLocation(curStack, tappos) ;
0912 printf("\n") ;
0913 dumpRepetitionLevels() ;
0914 dumpStack(curStack) ; printf("\n") ;
0915 #endif
b4daa24319 Shre*0916 }
0917
feb7fa5d1e dngo*0918
0919
b4daa24319 Shre*0920 void adStack_endRepeat() {
feb7fa5d1e dngo*0921 #ifdef ADSTACK_TRACE
0922 printf("BEFORE END REPEAT AT ") ;
0923 showLocation(curStack, tappos) ;
0924 printf("\n") ;
0925 dumpRepetitionLevels() ;
0926 dumpStack(curStack) ; printf("\n") ;
0927 #endif
b4daa24319 Shre*0928
0929 RepetitionLevel *topActive = topRepetitionPoint ;
0930 while (!topActive->active) {
0931 topActive = topActive->previous ;
0932 }
0933 topActive->active = 0 ;
feb7fa5d1e dngo*0934
0935 if (!(topActive->previous!=NULL &&
0936 topActive->previous->freePushBlock == topActive->freePushBlock)) {
0937
0938
0939
0940 DoubleChainedBlock *eraseBlockFrom = curStack ;
0941 if (topActive->previous!=NULL
0942 && topActive->previous->freePushBlock->next
0943 && topActive->previous->freePushBlock->next->rank > curStack->rank) {
0944 eraseBlockFrom = topActive->previous->freePushBlock->next ;
0945 }
0946
0947 DoubleChainedBlock *eraseBlockTo = topActive->freePushBlock ;
0948 #ifdef ADSTACK_TRACE
0949 printf(" erase all files from %02i up to %02i\n",
0950 (eraseBlockFrom ? eraseBlockFrom->rank : -1),
0951 (eraseBlockTo ? eraseBlockTo->rank : -1)) ;
0952 #endif
0953 #ifdef ADSTACK_PREFETCH
0954
0955 pthread_mutex_lock(&fileStorageMutex) ;
0956 #endif
0957 while (eraseBlockFrom) {
0958 if (eraseBlockFrom->rank!=eraseBlockFrom->toContents->rank) {
0959 removeStorageFile(eraseBlockFrom->rank) ;
0960 }
0961 if (eraseBlockFrom->rank==eraseBlockFrom->toContents->rank) {
0962 if (eraseBlockFrom->toContents->state==STORED
0963 || eraseBlockFrom==topActive->freePushBlock) {
0964 removeStorageFile(eraseBlockFrom->toContents->rank) ;
0965 eraseBlockFrom->toContents->state = INUSE ;
0966 }
0967 if (eraseBlockFrom!=curStack && spaceBeingDone!=eraseBlockFrom->toContents
0968 && !enqueued(eraseBlockFrom->toContents)) {
0969 eraseBlockFrom->toContents->rank = 0 ;
0970 eraseBlockFrom->toContents->state = STORED ;
0971 }
0972 }
0973 if (eraseBlockFrom==eraseBlockTo) {
0974 eraseBlockFrom = NULL ;
0975 } else {
0976 eraseBlockFrom = eraseBlockFrom->next ;
0977 }
0978 }
0979 #ifdef ADSTACK_PREFETCH
0980 pthread_mutex_unlock(&fileStorageMutex) ;
0981
0982 #endif
0983 }
b4daa24319 Shre*0984
0985 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*0986 #ifdef ADSTACK_TRACE
0987 printf(">AFTER END REPEAT AT ") ;
0988 showLocation(curStack, tappos) ;
0989 printf("\n") ;
0990 dumpRepetitionLevels() ;
0991 dumpStack(curStack) ; printf("\n") ;
0992 #endif
0993 }
0994
0995
0996
0997
0998 void storeInFile(BlockContents* blockContents) {
0999 sprintf(tapStackFileName, "tapStack%05i\0", blockContents->rank) ;
1000 FILE *tapStackFile = fopen(tapStackFileName, "wb") ;
1001 fwrite(blockContents->contents, 1, ADSTACK_BLOCK_SIZE, tapStackFile) ;
1002 fclose(tapStackFile) ;
1003 }
1004
1005
1006 void restoreFromFile(BlockContents* blockContents ) {
1007 sprintf(tapStackFileName, "tapStack%05i\0", blockContents->rank) ;
1008 FILE *tapStackFile = fopen(tapStackFileName, "rb") ;
1009 fread(blockContents->contents, 1, ADSTACK_BLOCK_SIZE, tapStackFile) ;
1010 fclose(tapStackFile) ;
1011 }
1012
1013
1014 void removeStorageFile(int blockRank) {
1015 char tapStackFileNameBis[14] ;
1016 sprintf(tapStackFileNameBis, "tapStack%05i\0", blockRank) ;
1017 #ifdef ADSTACK_TRACE
1018 printf(" Remove storage file %s\n", tapStackFileNameBis) ;
1019 #endif
1020 remove(tapStackFileNameBis) ;
1021 }
1022
1023
1024 BlockContents* assignSpace(int blockRank) {
1025 BlockContents* space ;
1026 int index = (blockRank-1)%ADSTACK_MAX_SPACES ;
1027 space = allBlockContents[index] ;
1028 if (!space) {
1029 space = (BlockContents*)malloc(sizeof(BlockContents)) ;
1030 if (!space) {
1031 printf("Out of memory while creating a BlockContents.\n") ;
1032 exit(0) ;
1033 }
1034 #ifdef ADSTACK_TRACE
1035 space->id = index ;
1036 #endif
1037
1038 space->rank = 0 ;
1039 space->state = STORED ;
1040 allBlockContents[index] = space ;
b4daa24319 Shre*1041 }
feb7fa5d1e dngo*1042 return space ;
1043 }
1044
1045 #ifdef ADSTACK_PREFETCH
1046
1047 void* manageFileStorage(void *arg) {
1048 struct timespec ts;
1049
1050 pthread_mutex_lock(&fileStorageMutex) ;
1051 while (1) {
1052 while (fileActionQueueHead==NULL) {
1053 #ifdef ADSTACK_TRACE
1054 clock_gettime(CLOCK_REALTIME, &ts);
1055 printf("t%09i------------------ Waiting in manage\n", ts.tv_nsec) ;
1056 #endif
1057 int rt = 0 ;
1058
1059
1060
1061 pthread_cond_wait(&enqueuedStorageCV, &fileStorageMutex) ;
1062 #ifdef ADSTACK_TRACE
1063 clock_gettime(CLOCK_REALTIME, &ts);
1064 printf("t%09i------------------ Wait %s in manage\n", ts.tv_nsec, (rt ? "timed out" : "woke up")) ;
1065 #endif
1066 }
1067 #ifdef ADSTACK_TRACE
1068 clock_gettime(CLOCK_REALTIME, &ts);
1069 printf("t%09i------------------ Manage file action queue:", ts.tv_nsec) ; dumpFileActionQueue() ; printf("\n") ;
1070 #endif
1071 fileActionBeingDone = fileActionQueueHead->action ;
1072 if (fileActionBeingDone==STORE) {
1073 spaceBeingDone = popHeadFileAction() ;
1074 rankBeingDone = spaceBeingDone->rank ;
1075 } else {
1076 rankBeingDone = fileActionQueueHead->restoredRank ;
1077 spaceBeingDone = popHeadFileAction() ;
1078 spaceBeingDone->rank = rankBeingDone ;
1079 }
1080 pthread_mutex_unlock(&fileStorageMutex) ;
1081
1082 #ifdef ADSTACK_TRACE
1083 clock_gettime(CLOCK_REALTIME, &ts);
1084 if (fileActionBeingDone==STORE) {
1085 printf("t%09i------------------ Going to store %04i from (%c: %02i %s)\n", ts.tv_nsec,
1086 spaceBeingDone->rank,
1087 'a'+spaceBeingDone->id,
1088 spaceBeingDone->rank,
1089 stateNames[spaceBeingDone->state]) ;
1090 } else if (fileActionBeingDone==RESTORE) {
1091 printf("t%09i------------------ Going to restore %04i into (%c: %02i %s)\n", ts.tv_nsec,
1092 spaceBeingDone->rank,
1093 'a'+spaceBeingDone->id,
1094 spaceBeingDone->rank,
1095 stateNames[spaceBeingDone->state]) ;
1096 }
1097 #endif
1098 if (fileActionBeingDone==STORE) {
1099 storeInFile(spaceBeingDone) ;
1100 } else if (fileActionBeingDone==RESTORE) {
1101 restoreFromFile(spaceBeingDone) ;
1102 }
1103
1104 pthread_mutex_lock(&fileStorageMutex) ;
1105 spaceBeingDone->state = STORED ;
1106 #ifdef ADSTACK_TRACE
1107 struct timespec ts;
1108 clock_gettime(CLOCK_REALTIME, &ts);
1109 printf("t%09i------------------ %s (%c: %02i %s) done, send signal doneStoreOrRestoreCV\n",
1110 ts.tv_nsec, (fileActionBeingDone==STORE ? "Store" : "Restore"),
1111 'a'+spaceBeingDone->id,
1112 spaceBeingDone->rank, stateNames[spaceBeingDone->state]) ;
1113 #endif
1114 fileActionBeingDone = NOACTION ;
1115 spaceBeingDone = NULL ;
1116 rankBeingDone = -1 ;
1117 pthread_cond_signal(&doneStoreOrRestoreCV) ;
1118 }
1119 pthread_mutex_unlock(&fileStorageMutex) ;
1120
b4daa24319 Shre*1121 }
feb7fa5d1e dngo*1122 #endif
b4daa24319 Shre*1123
feb7fa5d1e dngo*1124
b4daa24319 Shre*1125
feb7fa5d1e dngo*1126
1127
b4daa24319 Shre*1128 char* pushBlock() {
feb7fa5d1e dngo*1129 struct timespec ts;
b4daa24319 Shre*1130 if (curStack && curStack->next) {
1131 curStack = curStack->next ;
1132 } else {
1133 DoubleChainedBlock *newStack = (DoubleChainedBlock*)malloc(sizeof(DoubleChainedBlock)) ;
feb7fa5d1e dngo*1134 if (!newStack) {
1135 printf("Out of memory while creating a DoubleChainedBlock.\n") ;
b4daa24319 Shre*1136 exit(0) ;
1137 }
feb7fa5d1e dngo*1138 newStack->toContents = NULL ;
b4daa24319 Shre*1139 if(curStack != NULL) {
1140 curStack->next = newStack ;
1141 newStack->rank = curStack->rank + 1 ;
1142 } else {
1143 newStack->rank = 1 ;
feb7fa5d1e dngo*1144 #ifdef ADSTACK_PREFETCH
1145
1146 int errCode = 0 ;
1147 if ((errCode = pthread_mutex_init(&fileStorageMutex, NULL)) != 0) {
1148 printf("Error creating mutex. Error code:%i\n", errCode) ;
1149 }
1150 if ((errCode = pthread_cond_init(&enqueuedStorageCV, NULL)) != 0) {
1151 printf("Error creating condition variable enqueuedStorageCV. Error code:%i\n", errCode) ;
1152 }
1153 if ((errCode = pthread_cond_init(&doneStoreOrRestoreCV, NULL)) != 0) {
1154 printf("Error creating condition variable doneStoreOrRestoreCV. Error code:%i\n", errCode) ;
1155 }
1156 if ((errCode = pthread_create(&fileStorageThread, NULL, manageFileStorage, NULL)) != 0) {
1157 printf("Error creating thread. Error code:%i\n", errCode) ;
1158 }
1159 #endif
b4daa24319 Shre*1160 }
feb7fa5d1e dngo*1161 newStack->toContents = NULL ;
b4daa24319 Shre*1162 newStack->prev = curStack ;
1163 newStack->next = NULL ;
1164 curStack = newStack ;
1165 }
feb7fa5d1e dngo*1166 BlockContents *space = curStack->toContents ;
1167 if (!space) {
1168 space = assignSpace(curStack->rank);
1169 curStack->toContents = space ;
1170 }
1171 #ifdef ADSTACK_PREFETCH
1172
1173 pthread_mutex_lock(&fileStorageMutex) ;
1174 preStore() ;
1175 waitForward() ;
1176 space->state = INUSE ;
1177 space->rank = curStack->rank ;
1178 pthread_mutex_unlock(&fileStorageMutex) ;
1179
1180 #else
1181 checkForward() ;
1182 space->state = INUSE ;
1183 space->rank = curStack->rank ;
1184 #endif
1185 #ifdef ADSTACK_TRACE
1186 clock_gettime(CLOCK_REALTIME, &ts);
1187 printf("t%09i %02i => %02i\n", ts.tv_nsec, curStack->rank - 1,
1188 curStack->rank) ;
1189 dumpStack(curStack) ; printf("\n") ;
1190 #endif
1191 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1192 if (curStack->rank > maxBlocks) maxBlocks = curStack->rank ;
1193 #endif
feb7fa5d1e dngo*1194 return space->contents ;
b4daa24319 Shre*1195 }
1196
feb7fa5d1e dngo*1197
1198
b4daa24319 Shre*1199 char* popBlock() {
1200 DoubleChainedBlock *oldTopStack = curStack ;
feb7fa5d1e dngo*1201 struct timespec ts;
b4daa24319 Shre*1202 curStack = curStack->prev ;
feb7fa5d1e dngo*1203 #ifdef ADSTACK_PREFETCH
1204
1205 pthread_mutex_lock(&fileStorageMutex) ;
1206 int oldInRepetition =
1207 (topRepetitionPoint && oldTopStack->rank <= topRepetitionPoint->freePushBlock->rank) ;
1208 if (!oldInRepetition && spaceBeingDone!=oldTopStack->toContents
1209 && !enqueued(oldTopStack->toContents)) {
1210 oldTopStack->toContents->rank = 0 ;
1211 oldTopStack->toContents->state = STORED ;
1212 }
1213 preRestore() ;
1214 waitBackward() ;
1215 if (!topRepetitionPoint || curStack->rank >= topRepetitionPoint->freePushBlock->rank) {
1216 if ((!topRepetitionPoint || curStack != topRepetitionPoint->freePushBlock)
1217 && curStack->toContents->state==STORED) {
1218 removeStorageFile(curStack->toContents->rank) ;
b4daa24319 Shre*1219 }
feb7fa5d1e dngo*1220
1221 curStack->toContents->state = INUSE ;
b4daa24319 Shre*1222 }
feb7fa5d1e dngo*1223 curStack->toContents->rank = curStack->rank ;
1224 pthread_mutex_unlock(&fileStorageMutex) ;
1225
1226 #else
1227 int oldInRepetition =
1228 (topRepetitionPoint && oldTopStack->rank <= topRepetitionPoint->freePushBlock->rank) ;
1229 if (!oldInRepetition && spaceBeingDone!=oldTopStack->toContents
1230 && !enqueued(oldTopStack->toContents)) {
1231 oldTopStack->toContents->rank = 0 ;
1232 oldTopStack->toContents->state = STORED ;
1233 }
1234 checkBackward() ;
1235 if (!topRepetitionPoint || curStack->rank >= topRepetitionPoint->freePushBlock->rank) {
1236 if ((!topRepetitionPoint || curStack != topRepetitionPoint->freePushBlock)
1237 && curStack->toContents->state==STORED) {
1238 removeStorageFile(curStack->toContents->rank) ;
1239 }
1240
1241 curStack->toContents->state = INUSE ;
1242 }
1243 curStack->toContents->rank = curStack->rank ;
1244 #endif
1245 #ifdef ADSTACK_TRACE
1246 clock_gettime(CLOCK_REALTIME, &ts);
1247 printf("t%09i %02i <= %02i\n", ts.tv_nsec, curStack->rank, curStack->rank + 1) ;
1248 dumpStack(curStack) ; printf("\n") ;
1249 #endif
1250 return (curStack ? curStack->toContents->contents : NULL) ;
b4daa24319 Shre*1251 }
1252
feb7fa5d1e dngo*1253
1254
1255
b4daa24319 Shre*1256
1257
1258
1259
1260
1261
1262
1263 void pushNArray(char *x, int nbChars) {
1264 do {
feb7fa5d1e dngo*1265 int wsize = tappos+nbChars<ADSTACK_BLOCK_SIZE?nbChars:ADSTACK_BLOCK_SIZE-tappos ;
b4daa24319 Shre*1266 if(wsize > 0) {
1267 memcpy(tapblock+tappos,x,wsize) ;
1268 nbChars -= wsize ;
1269 x += wsize ;
1270 tappos += wsize ;
1271 }
1272 else if (nbChars > 0) {
1273 tapblock = pushBlock() ;
1274 tappos = 0 ;
1275 }
1276 } while(nbChars > 0) ;
1277 }
1278
1279 void popNArray(char *x, int nbChars) {
1280 x += nbChars ;
1281 do {
1282 int wsize = (nbChars<tappos)?nbChars:tappos ;
1283 if(wsize > 0) {
1284 memcpy(x-wsize,tapblock+tappos-wsize,wsize) ;
1285 nbChars -= wsize ;
1286 x -= wsize ;
1287 tappos -= wsize ;
1288 }
1289 else if (nbChars > 0) {
1290 tapblock = popBlock() ;
feb7fa5d1e dngo*1291 tappos = ADSTACK_BLOCK_SIZE ;
b4daa24319 Shre*1292 }
1293 } while(nbChars > 0) ;
1294 }
1295
1296 void pushInteger4Array(int *x, int n) {
1297 if (topRepetitionPoint) checkPushInReadOnly() ;
1298 pushNArray((char *)x,(int)(n*4)) ;
feb7fa5d1e dngo*1299 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1300 pushPopTraffic += (int)(n*4) ;
1301 #endif
1302 }
1303
1304 void popInteger4Array(int *x, int n) {
1305 popNArray((char *)x,(int)(n*4)) ;
1306 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1307 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1308 pushPopTraffic += (int)(n*4) ;
1309 #endif
1310 }
1311
1312 void pushInteger8Array(long *x, int n) {
1313 if (topRepetitionPoint) checkPushInReadOnly() ;
1314 pushNArray((char *)x,(int)(n*8)) ;
feb7fa5d1e dngo*1315 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1316 pushPopTraffic += (int)(n*8) ;
1317 #endif
1318 }
1319
1320 void popInteger8Array(long *x, int n) {
1321 popNArray((char *)x,(int)(n*8)) ;
1322 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1323 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1324 pushPopTraffic += (int)(n*8) ;
1325 #endif
1326 }
1327
1328 void pushReal4Array(float *x, int n) {
1329 if (topRepetitionPoint) checkPushInReadOnly() ;
1330 pushNArray((char *)x,(int)(n*4)) ;
feb7fa5d1e dngo*1331 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1332 pushPopTraffic += (int)(n*4) ;
1333 #endif
1334 }
1335
1336 void popReal4Array(float *x, int n) {
1337 popNArray((char *)x,(int)(n*4)) ;
1338 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1339 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1340 pushPopTraffic += (int)(n*4) ;
1341 #endif
1342 }
1343
1344 void pushReal8Array(double *x, int n) {
1345 if (topRepetitionPoint) checkPushInReadOnly() ;
1346 pushNArray((char *)x,(int)(n*8)) ;
feb7fa5d1e dngo*1347 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1348 pushPopTraffic += (int)(n*8) ;
1349 #endif
1350 }
1351
1352 void popReal8Array(double *x, int n) {
1353 popNArray((char *)x,(int)(n*8)) ;
1354 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1355 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1356 pushPopTraffic += (int)(n*8) ;
1357 #endif
1358 }
1359
feb7fa5d1e dngo*1360 void pushReal16Array(long double *x, int n) {
1361 if (topRepetitionPoint) checkPushInReadOnly() ;
1362 pushNArray((char *)x,(int)(n*16)) ;
1363 #ifdef ADSTACK_PROFILE
1364 pushPopTraffic += (int)(n*16) ;
1365 #endif
1366 }
1367
1368 void popReal16Array(long double *x, int n) {
1369 popNArray((char *)x,(int)(n*16)) ;
1370 if (topRepetitionPoint) checkPopToReadOnly() ;
1371 #ifdef ADSTACK_PROFILE
1372 pushPopTraffic += (int)(n*16) ;
1373 #endif
1374 }
1375
b4daa24319 Shre*1376 void pushComplex8Array(ccmplx *x, int n) {
1377 if (topRepetitionPoint) checkPushInReadOnly() ;
1378 pushNArray((char *)x,(int)(n*8)) ;
feb7fa5d1e dngo*1379 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1380 pushPopTraffic += (int)(n*8) ;
1381 #endif
1382 }
1383
1384 void popComplex8Array(ccmplx *x, int n) {
1385 popNArray((char *)x,(int)(n*8)) ;
1386 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1387 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1388 pushPopTraffic += (int)(n*8) ;
1389 #endif
1390 }
1391
1392 void pushComplex16Array(double complex *x, int n) {
1393 if (topRepetitionPoint) checkPushInReadOnly() ;
1394 pushNArray((char *)x,(int)(n*16)) ;
feb7fa5d1e dngo*1395 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1396 pushPopTraffic += (int)(n*16) ;
1397 #endif
1398 }
1399
1400 void popComplex16Array(double complex *x, int n) {
1401 popNArray((char *)x,(int)(n*16)) ;
1402 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1403 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1404 pushPopTraffic += (int)(n*16) ;
1405 #endif
1406 }
1407
1408 void pushCharacterArray(char *x, int n) {
1409 if (topRepetitionPoint) checkPushInReadOnly() ;
1410 pushNArray(x,(int)n) ;
feb7fa5d1e dngo*1411 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1412 pushPopTraffic += (int)n ;
1413 #endif
1414 }
1415
1416 void popCharacterArray(char *x, int n) {
1417 popNArray(x,(int)n) ;
1418 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1419 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1420 pushPopTraffic += (int)n ;
1421 #endif
1422 }
1423
feb7fa5d1e dngo*1424
b4daa24319 Shre*1425
1426 void pushCharacter(char val) {
1427 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1428 if(tappos + 1 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1429 pushNArray((char*)&val, 1) ;
1430 }
1431 else {
1432 *(char*)(tapblock+tappos) = val;
1433 tappos = tappos + 1 ;
1434 }
feb7fa5d1e dngo*1435 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1436 pushPopTraffic += 1 ;
1437 #endif
1438 }
1439
1440 void popCharacter(char * val) {
1441 if(tappos - 1 < 0) {
1442 popNArray((char*)val, 1) ;
1443 }
1444 else {
1445 tappos = tappos - 1 ;
1446 *val = *(char*)(tapblock+tappos);
1447 }
1448 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1449 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1450 pushPopTraffic += 1 ;
1451 #endif
1452 }
1453
1454 void pushReal4(float val) {
1455 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1456 if(tappos + 4 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1457 pushNArray((char*)&val, 4) ;
1458 }
1459 else {
1460 *(float*)(tapblock+tappos) = val;
1461 tappos = tappos + 4 ;
1462 }
feb7fa5d1e dngo*1463 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1464 pushPopTraffic += 4 ;
1465 #endif
1466 }
1467
1468 void popReal4(float * val) {
1469 if(tappos - 4 < 0) {
1470 popNArray((char*)val, 4) ;
1471 }
1472 else {
1473 tappos = tappos - 4 ;
1474 *val = *(float*)(tapblock+tappos);
1475 }
1476 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1477 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1478 pushPopTraffic += 4 ;
1479 #endif
1480 }
1481
1482 void pushReal8(double val) {
1483 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1484 if(tappos + 8 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1485 pushNArray((char*)&val, 8) ;
1486 }
1487 else {
1488 *(double*)(tapblock+tappos) = val;
1489 tappos = tappos + 8 ;
1490 }
feb7fa5d1e dngo*1491 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1492 pushPopTraffic += 8 ;
1493 #endif
1494 }
1495
1496 void popReal8(double * val) {
1497 if(tappos - 8 < 0) {
1498 popNArray((char*)val, 8) ;
1499 }
1500 else {
1501 tappos = tappos - 8 ;
1502 *val = *(double*)(tapblock+tappos);
1503 }
1504 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1505 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1506 pushPopTraffic += 8 ;
1507 #endif
1508 }
1509
feb7fa5d1e dngo*1510 void pushReal16(long double *val) {
1511 if (topRepetitionPoint) checkPushInReadOnly() ;
1512 if(tappos + 16 > ADSTACK_BLOCK_SIZE) {
1513 pushNArray((char*)val, 16) ;
1514 }
1515 else {
1516 memcpy(tapblock+tappos, (void *)val, 16);
1517 tappos = tappos + 16 ;
1518 }
1519 #ifdef ADSTACK_PROFILE
1520 pushPopTraffic += 16 ;
1521 #endif
1522 }
1523
1524 void popReal16(long double *val) {
1525 if(tappos - 16 < 0) {
1526 popNArray((char*)val, 16) ;
1527 }
1528 else {
1529 tappos = tappos - 16 ;
1530 memcpy((void *)val, tapblock+tappos, 16) ;
1531 }
1532 if (topRepetitionPoint) checkPopToReadOnly() ;
1533 #ifdef ADSTACK_PROFILE
1534 pushPopTraffic += 16 ;
1535 #endif
1536 }
1537
b4daa24319 Shre*1538 void pushInteger4(int val) {
1539 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1540 if(tappos + 4 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1541 pushNArray((char*)&val, 4) ;
1542 }
1543 else {
1544 *(int*)(tapblock+tappos) = val;
1545 tappos = tappos + 4 ;
1546 }
feb7fa5d1e dngo*1547 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1548 pushPopTraffic += 4 ;
1549 #endif
1550 }
1551
1552 void popInteger4(int * val) {
1553 if(tappos - 4 < 0) {
1554 popNArray((char*)val, 4) ;
1555 }
1556 else {
1557 tappos = tappos - 4 ;
1558 *val = *(int*)(tapblock+tappos);
1559 }
1560 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1561 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1562 pushPopTraffic += 4 ;
1563 #endif
1564 }
1565
1566 void pushInteger8(long val) {
1567 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1568 if(tappos + 8 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1569 pushNArray((char*)&val, 8) ;
1570 }
1571 else {
1572 *(long*)(tapblock+tappos) = val;
1573 tappos = tappos + 8 ;
1574 }
feb7fa5d1e dngo*1575 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1576 pushPopTraffic += 8 ;
1577 #endif
1578 }
1579
1580 void popInteger8(long * val) {
1581 if(tappos - 8 < 0) {
1582 popNArray((char*)val, 8) ;
1583 }
1584 else {
1585 tappos = tappos - 8 ;
1586 *val = *(long*)(tapblock+tappos);
1587 }
1588 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1589 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1590 pushPopTraffic += 8 ;
1591 #endif
1592 }
1593
1594 void pushComplex8(ccmplx val) {
1595 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1596 if(tappos + 8 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1597 pushNArray((char*)&val, 8) ;
1598 }
1599 else {
1600 *(ccmplx*)(tapblock+tappos) = val;
1601 tappos = tappos + 8 ;
1602 }
feb7fa5d1e dngo*1603 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1604 pushPopTraffic += 8 ;
1605 #endif
1606 }
1607
1608 void popComplex8(ccmplx * val) {
1609 if(tappos - 8 < 0) {
1610 popNArray((char*)val, 8) ;
1611 }
1612 else {
1613 tappos = tappos - 8 ;
1614 *val = *(ccmplx*)(tapblock+tappos);
1615 }
1616 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1617 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1618 pushPopTraffic += 8 ;
1619 #endif
1620 }
1621
1622 void pushComplex16(double complex val) {
1623 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1624 if(tappos + 16 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1625 pushNArray((char*)&val, 16) ;
1626 }
1627 else {
1628 *(double complex *)(tapblock+tappos) = val;
1629 tappos = tappos + 16 ;
1630 }
feb7fa5d1e dngo*1631 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1632 pushPopTraffic += 16 ;
1633 #endif
1634 }
1635
1636 void popComplex16(double complex *val) {
1637 if(tappos - 16 < 0) {
1638 popNArray((char*)val, 16) ;
1639 }
1640 else {
1641 tappos = tappos - 16 ;
1642 *val = *(double complex *)(tapblock+tappos);
1643 }
1644 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1645 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1646 pushPopTraffic += 16 ;
1647 #endif
1648 }
1649
1650 void pushPointer4(void * val) {
1651 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1652 if(tappos + 4 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1653 pushNArray((char*)&val, 4) ;
1654 }
1655 else {
1656 *(void**)(tapblock+tappos) = val;
1657 tappos = tappos + 4 ;
1658 }
feb7fa5d1e dngo*1659 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1660 pushPopTraffic += 4 ;
1661 #endif
1662 }
1663
1664 void popPointer4(void ** val) {
1665 if(tappos - 4 < 0) {
1666 popNArray((char*)val, 4) ;
1667 }
1668 else {
1669 tappos = tappos - 4 ;
1670 *val = *(void**)(tapblock+tappos);
1671 }
1672 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1673 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1674 pushPopTraffic += 4 ;
1675 #endif
1676 }
1677
1678 void pushPointer8(void * val) {
1679 if (topRepetitionPoint) checkPushInReadOnly() ;
feb7fa5d1e dngo*1680 if(tappos + 8 > ADSTACK_BLOCK_SIZE) {
b4daa24319 Shre*1681 pushNArray((char*)&val, 8) ;
1682 }
1683 else {
1684 *(void**)(tapblock+tappos) = val;
1685 tappos = tappos + 8 ;
1686 }
feb7fa5d1e dngo*1687 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1688 pushPopTraffic += 8 ;
1689 #endif
1690 }
1691
1692 void popPointer8(void ** val) {
1693 if(tappos - 8 < 0) {
1694 popNArray((char*)val, 8) ;
1695 }
1696 else {
1697 tappos = tappos - 8 ;
1698 *val = *(void**)(tapblock+tappos);
1699 }
1700 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*1701 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1702 pushPopTraffic += 8 ;
1703 #endif
1704 }
1705
feb7fa5d1e dngo*1706
b4daa24319 Shre*1707
1708 void pushBit(int x) {
1709 adbitbuf<<=1 ;
1710 if (x) ++adbitbuf ;
1711 if (adbitibuf>=31) {
1712 pushNArray((char *)&adbitbuf, 4) ;
1713 adbitbuf = 0 ;
1714 adbitibuf = 0 ;
feb7fa5d1e dngo*1715 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1716 pushPopTraffic += 4 ;
1717 #endif
1718 } else
1719 ++adbitibuf ;
1720 }
1721
1722 int popBit() {
1723 if (adbitibuf<=0) {
1724 popNArray((char *)&adbitbuf, 4) ;
1725 adbitibuf = 31 ;
feb7fa5d1e dngo*1726 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*1727 pushPopTraffic += 4 ;
1728 #endif
1729 } else
1730 --adbitibuf ;
1731 int result = adbitbuf%2 ;
1732 adbitbuf>>=1 ;
1733 return result ;
1734 }
1735
feb7fa5d1e dngo*1736
b4daa24319 Shre*1737
1738 void pushBoolean(int x) {
1739 if (topRepetitionPoint) checkPushInReadOnly() ;
1740 pushBit(x) ;
1741 }
1742
1743
1744 void popBoolean(int *x) {
1745 *x = popBit() ;
1746 if (topRepetitionPoint) checkPopToReadOnly() ;
1747 }
1748
feb7fa5d1e dngo*1749
b4daa24319 Shre*1750
1751 void pushControl1b(int cc) {
1752 if (topRepetitionPoint) checkPushInReadOnly() ;
1753 pushBit(cc) ;
1754 }
1755
1756 void popControl1b(int *cc) {
1757 *cc = popBit() ;
1758 if (topRepetitionPoint) checkPopToReadOnly() ;
1759 }
1760
1761 void pushControl2b(int cc) {
1762 if (topRepetitionPoint) checkPushInReadOnly() ;
1763 pushBit(cc%2) ;
1764 cc>>=1 ;
1765 pushBit(cc) ;
1766 }
1767
1768 void popControl2b(int *cc) {
1769 *cc = (popBit()?2:0) ;
1770 if (popBit()) (*cc)++ ;
1771 if (topRepetitionPoint) checkPopToReadOnly() ;
1772 }
1773
1774 void pushControl3b(int cc) {
1775 if (topRepetitionPoint) checkPushInReadOnly() ;
1776 pushBit(cc%2) ;
1777 cc>>=1 ;
1778 pushBit(cc%2) ;
1779 cc>>=1 ;
1780 pushBit(cc) ;
1781 }
1782
1783 void popControl3b(int *cc) {
1784 *cc = (popBit()?2:0) ;
1785 if (popBit()) (*cc)++ ;
1786 (*cc) <<= 1 ;
1787 if (popBit()) (*cc)++ ;
1788 if (topRepetitionPoint) checkPopToReadOnly() ;
1789 }
1790
1791 void pushControl4b(int cc) {
1792 if (topRepetitionPoint) checkPushInReadOnly() ;
1793 pushBit(cc%2) ;
1794 cc>>=1 ;
1795 pushBit(cc%2) ;
1796 cc>>=1 ;
1797 pushBit(cc%2) ;
1798 cc>>=1 ;
1799 pushBit(cc) ;
1800 }
1801
1802 void popControl4b(int *cc) {
1803 *cc = (popBit()?2:0) ;
1804 if (popBit()) (*cc)++ ;
1805 (*cc) <<= 1 ;
1806 if (popBit()) (*cc)++ ;
1807 (*cc) <<= 1 ;
1808 if (popBit()) (*cc)++ ;
1809 if (topRepetitionPoint) checkPopToReadOnly() ;
1810 }
1811
1812 void pushControl5b(int cc) {
1813 if (topRepetitionPoint) checkPushInReadOnly() ;
1814 pushBit(cc%2) ;
1815 cc>>=1 ;
1816 pushBit(cc%2) ;
1817 cc>>=1 ;
1818 pushBit(cc%2) ;
1819 cc>>=1 ;
1820 pushBit(cc%2) ;
1821 cc>>=1 ;
1822 pushBit(cc) ;
1823 }
1824
1825 void popControl5b(int *cc) {
1826 *cc = (popBit()?2:0) ;
1827 if (popBit()) (*cc)++ ;
1828 (*cc) <<= 1 ;
1829 if (popBit()) (*cc)++ ;
1830 (*cc) <<= 1 ;
1831 if (popBit()) (*cc)++ ;
1832 (*cc) <<= 1 ;
1833 if (popBit()) (*cc)++ ;
1834 if (topRepetitionPoint) checkPopToReadOnly() ;
1835 }
1836
1837 void pushControl6b(int cc) {
1838 if (topRepetitionPoint) checkPushInReadOnly() ;
1839 pushBit(cc%2) ;
1840 cc>>=1 ;
1841 pushBit(cc%2) ;
1842 cc>>=1 ;
1843 pushBit(cc%2) ;
1844 cc>>=1 ;
1845 pushBit(cc%2) ;
1846 cc>>=1 ;
1847 pushBit(cc%2) ;
1848 cc>>=1 ;
1849 pushBit(cc) ;
1850 }
1851
1852 void popControl6b(int *cc) {
1853 *cc = (popBit()?2:0) ;
1854 if (popBit()) (*cc)++ ;
1855 (*cc) <<= 1 ;
1856 if (popBit()) (*cc)++ ;
1857 (*cc) <<= 1 ;
1858 if (popBit()) (*cc)++ ;
1859 (*cc) <<= 1 ;
1860 if (popBit()) (*cc)++ ;
1861 (*cc) <<= 1 ;
1862 if (popBit()) (*cc)++ ;
1863 if (topRepetitionPoint) checkPopToReadOnly() ;
1864 }
1865
1866 void pushControl7b(int cc) {
1867 if (topRepetitionPoint) checkPushInReadOnly() ;
1868 pushBit(cc%2) ;
1869 cc>>=1 ;
1870 pushBit(cc%2) ;
1871 cc>>=1 ;
1872 pushBit(cc%2) ;
1873 cc>>=1 ;
1874 pushBit(cc%2) ;
1875 cc>>=1 ;
1876 pushBit(cc%2) ;
1877 cc>>=1 ;
1878 pushBit(cc%2) ;
1879 cc>>=1 ;
1880 pushBit(cc) ;
1881 }
1882
1883 void popControl7b(int *cc) {
1884 *cc = (popBit()?2:0) ;
1885 if (popBit()) (*cc)++ ;
1886 (*cc) <<= 1 ;
1887 if (popBit()) (*cc)++ ;
1888 (*cc) <<= 1 ;
1889 if (popBit()) (*cc)++ ;
1890 (*cc) <<= 1 ;
1891 if (popBit()) (*cc)++ ;
1892 (*cc) <<= 1 ;
1893 if (popBit()) (*cc)++ ;
1894 (*cc) <<= 1 ;
1895 if (popBit()) (*cc)++ ;
1896 if (topRepetitionPoint) checkPopToReadOnly() ;
1897 }
1898
1899 void pushControl8b(int cc) {
1900 if (topRepetitionPoint) checkPushInReadOnly() ;
1901 pushBit(cc%2) ;
1902 cc>>=1 ;
1903 pushBit(cc%2) ;
1904 cc>>=1 ;
1905 pushBit(cc%2) ;
1906 cc>>=1 ;
1907 pushBit(cc%2) ;
1908 cc>>=1 ;
1909 pushBit(cc%2) ;
1910 cc>>=1 ;
1911 pushBit(cc%2) ;
1912 cc>>=1 ;
1913 pushBit(cc%2) ;
1914 cc>>=1 ;
1915 pushBit(cc) ;
1916 }
1917
1918 void popControl8b(int *cc) {
1919 *cc = (popBit()?2:0) ;
1920 if (popBit()) (*cc)++ ;
1921 (*cc) <<= 1 ;
1922 if (popBit()) (*cc)++ ;
1923 (*cc) <<= 1 ;
1924 if (popBit()) (*cc)++ ;
1925 (*cc) <<= 1 ;
1926 if (popBit()) (*cc)++ ;
1927 (*cc) <<= 1 ;
1928 if (popBit()) (*cc)++ ;
1929 (*cc) <<= 1 ;
1930 if (popBit()) (*cc)++ ;
1931 (*cc) <<= 1 ;
1932 if (popBit()) (*cc)++ ;
1933 if (topRepetitionPoint) checkPopToReadOnly() ;
1934 }
1935
feb7fa5d1e dngo*1936 uint64_t adStack_getCurrentStackSize() {
1937 return curStack ? (curStack->rank-1)*ADSTACK_BLOCK_SIZE + tappos : 0;
1938 }
1939
1940
1941
1942 void showLocation(DoubleChainedBlock *locBlock, int loc) {
1943 printf("%1i.%05i", (locBlock ? locBlock->rank-1 : 0), loc) ;
1944 }
1945
1946 #ifdef ADSTACK_TRACE
1947 void dumpStackPrev(DoubleChainedBlock *st) {
1948 if (st) {
1949 if (st->rank==st->toContents->rank) {
1950 dumpStackPrev(st->prev) ;
1951 }
1952 printf("-->[%02i ", st->rank) ;
1953 if (st->toContents) {
1954 printf("(%c: %02i %s)",
1955 'a'+st->toContents->id,
1956 st->toContents->rank,
1957 stateNames[st->toContents->state]) ;
1958 } else {
1959 printf("null") ;
1960 }
1961 printf("]") ;
1962 }
1963 }
1964
1965 void dumpStackNext(DoubleChainedBlock *st) {
1966 if (st) {
1967 printf("..>[%02i ", st->rank) ;
1968 if (st->toContents) {
1969 printf("(%c: %02i %s)",
1970 'a'+st->toContents->id,
1971 st->toContents->rank,
1972 stateNames[st->toContents->state]) ;
1973 } else {
1974 printf("null") ;
1975 }
1976 printf("]") ;
1977 if (st->rank==st->toContents->rank) {
1978 dumpStackNext(st->next) ;
1979 }
1980 }
1981 }
1982
1983 void dumpStack(DoubleChainedBlock *st) {
1984 if (st) {
1985 printf(" ") ;
1986 dumpStackPrev(st->prev) ;
1987 printf(">>>[%02i ", st->rank) ;
1988 if (st->toContents) {
1989 printf("(%c: %02i %s)",
1990 'a'+st->toContents->id,
1991 st->toContents->rank,
1992 stateNames[st->toContents->state]) ;
1993 } else {
1994 printf("null") ;
1995 }
1996 printf("]") ;
1997 dumpStackNext(st->next) ;
1998 }
1999 }
2000
2001 void dumpFileActionQueue() {
2002 FileActionCell *inQueue = fileActionQueueHead ;
2003 if (!inQueue) {
2004 printf(" empty") ;
2005 } else {
2006 while (inQueue) {
2007 if (inQueue->action==STORE) {
2008 printf(" store (%c: %02i %s)",
2009 'a'+inQueue->space->id,
2010 inQueue->space->rank,
2011 stateNames[inQueue->space->state]) ;
2012 } else if (inQueue->action==RESTORE) {
2013 printf(" restore %02i into (%c: %02i %s)",
2014 inQueue->restoredRank,
2015 'a'+inQueue->space->id,
2016 inQueue->space->rank,
2017 stateNames[inQueue->space->state]) ;
2018 }
2019 inQueue = inQueue->next ;
2020 }
2021 }
2022 }
2023 #endif
2024
2025 void dumpContents(BlockContents* space) {
2026 for (int i=0 ; i<ADSTACK_BLOCK_SIZE ; ++i) {
2027 printf("%02x", (unsigned char)space->contents[i]) ;
2028 if (i%10==9) printf(" ") ;
2029 if (i%50==49) printf("\n") ;
2030 }
2031 }
2032
2033 void dumpRepetitionLevels() {
2034 RepetitionLevel *repetitionPoint = topRepetitionPoint ;
2035 while (repetitionPoint) {
2036 printf(" REPETITION LEVEL ACTIVE:%s BP:%s",
2037 (repetitionPoint->active?"yes":"no"),
2038 (repetitionPoint->hasBackPop?"yes":"no")) ;
2039 if (repetitionPoint->hasBackPop)
2040 {printf(" BP:") ; showLocation(repetitionPoint->backPopBlock, repetitionPoint->backPop) ;}
2041 if (repetitionPoint->resumePointBlock)
2042 {printf(" RP:") ; showLocation(repetitionPoint->resumePointBlock, repetitionPoint->resumePoint) ;}
2043 if (repetitionPoint->freePushBlock)
2044 {printf(" FP:") ; showLocation(repetitionPoint->freePushBlock, repetitionPoint->freePush) ;}
2045 printf("\n") ;
2046 repetitionPoint = repetitionPoint->previous ;
2047 if (repetitionPoint) printf(" ...in") ;
2048 }
2049 }
2050
2051 void showErrorContext() {
2052 struct timespec ts;
2053 clock_gettime(CLOCK_REALTIME, &ts);
2054 printf("t%09i ERROR AT:", ts.tv_nsec) ; showLocation(curStack, tappos) ;
2055 #ifdef ADSTACK_TRACE
2056 printf(" STACK:") ; dumpStack(curStack) ; printf("\n") ;
2057 printf("FILE ACTION QUEUE:\n") ;
2058 dumpFileActionQueue() ; printf("\n") ;
2059 #endif
2060 printf("REPETITION LEVELS:\n") ;
2061 dumpRepetitionLevels() ;
2062 }
b4daa24319 Shre*2063
2064 void adStack_showPeakSize() {
2065 printf("Peak stack size (%1li blocks): %1llu bytes\n",
feb7fa5d1e dngo*2066 maxBlocks, maxBlocks*((long int)ADSTACK_BLOCK_SIZE)) ;
b4daa24319 Shre*2067 }
2068
2069 void adStack_showTotalTraffic() {
feb7fa5d1e dngo*2070 printf("Total push/pop traffic %1lu bytes\n", pushPopTraffic) ;
b4daa24319 Shre*2071 }
2072
2073 void adStack_showStackSize(int label) {
2074 printf(" %i--> <",label) ;
feb7fa5d1e dngo*2075 printf("%"PRId64"", adStack_getCurrentStackSize());
2076
b4daa24319 Shre*2077 printf(">") ;
2078 }
2079
2080 void adStack_showStack(char *locationName) {
2081 if (!curStack || (tappos==0 && !curStack->prev)) {
2082 printf ("Stack at %s is empty\n", locationName) ;
2083 } else {
2084 printf ("Stack top at %s is %1i.%05i :\n", locationName, curStack->rank, tappos) ;
2085 int bytesToShow = 20 ;
2086 int blocksToShow = 3 ;
2087 DoubleChainedBlock *inStack = curStack ;
2088 int inPos = tappos ;
2089 while (blocksToShow>0 && inStack) {
2090 printf(" Block %d:", inStack->rank) ;
2091 while (bytesToShow>0 && inPos>0) {
feb7fa5d1e dngo*2092 printf(" %02x", (unsigned char)inStack->toContents->contents[--inPos]) ;
b4daa24319 Shre*2093 --bytesToShow ;
2094 }
2095 if (inPos>0)
2096 printf(" ...<%d more bytes>...", inPos) ;
2097 printf(" |\n") ;
2098 --blocksToShow ;
2099 inStack = inStack->prev ;
feb7fa5d1e dngo*2100 inPos = ADSTACK_BLOCK_SIZE ;
b4daa24319 Shre*2101 }
2102 if (inStack)
2103 printf(" %d more blocks below\n", inStack->rank) ;
2104 }
2105 if (adbitibuf==0) {
2106 printf("Bit buffer is empty\n") ;
2107 } else {
2108 printf("Bit buffer:%1i in %08x\n", adbitibuf, adbitbuf) ;
2109 }
2110 if (topRepetitionPoint) {
2111 printf("Repetition levels:\n ") ;
feb7fa5d1e dngo*2112 dumpRepetitionLevels() ;
b4daa24319 Shre*2113 }
2114 printf("----------------\n") ;
2115 }
2116
feb7fa5d1e dngo*2117
2118
b4daa24319 Shre*2119 int stackIsThreadSafe() {
2120 #ifdef _OPENMP
2121 return 1 ;
2122 #else
2123 return 0 ;
2124 #endif
2125 }
2126
2127
2128
2129 void adstack_startrepeat_() {
2130 adStack_startRepeat() ;
2131 }
2132
2133 void adstack_resetrepeat_() {
2134 adStack_resetRepeat() ;
2135 }
2136
2137 void adstack_endrepeat_() {
2138 adStack_endRepeat() ;
2139 }
2140
2141 void pushinteger4array_(int *ii, int *ll) {
2142 pushInteger4Array(ii, *ll) ;
2143 }
2144
2145 void popinteger4array_(int *ii, int *ll) {
2146 popInteger4Array(ii, *ll) ;
2147 }
2148
2149 void pushinteger8array_(long *ii, int *ll) {
2150 pushInteger8Array(ii, *ll) ;
2151 }
2152
2153 void popinteger8array_(long *ii, int *ll) {
2154 popInteger8Array(ii, *ll) ;
2155 }
2156
2157 void pushreal4array_(float *ii, int *ll) {
2158 pushReal4Array(ii, *ll) ;
2159 }
2160
2161 void popreal4array_(float *ii, int *ll) {
2162 popReal4Array(ii, *ll) ;
2163 }
2164
2165 void pushreal8array_(double *ii, int *ll) {
2166 pushReal8Array(ii, *ll) ;
2167 }
2168
2169 void popreal8array_(double *ii, int *ll) {
2170 popReal8Array(ii, *ll) ;
2171 }
2172
feb7fa5d1e dngo*2173 void pushreal16array_(long double *ii, int *ll) {
2174 pushReal16Array(ii, *ll) ;
2175 }
2176
2177 void popreal16array_(long double *ii, int *ll) {
2178 popReal16Array(ii, *ll) ;
2179 }
2180
b4daa24319 Shre*2181 void pushcomplex8array_(ccmplx *ii, int *ll) {
2182 pushComplex8Array(ii, *ll) ;
2183 }
2184
2185 void popcomplex8array_(ccmplx *ii, int *ll) {
2186 popComplex8Array(ii, *ll) ;
2187 }
2188
2189 void pushcomplex16array_(cdcmplx *ii, int *ll) {
2190 pushComplex16Array((double complex *)ii, *ll) ;
2191 }
2192
2193 void popcomplex16array_(cdcmplx *ii, int *ll) {
2194 popComplex16Array((double complex *)ii, *ll) ;
2195 }
2196
2197 void pushcharacterarray_(char *ii, int *ll) {
2198 pushCharacterArray(ii, *ll) ;
2199 }
2200
2201 void popcharacterarray_(char *ii, int *ll) {
2202 popCharacterArray(ii, *ll) ;
2203 }
2204
2205 void pushbooleanarray_(char *x, int *n) {
2206 if (topRepetitionPoint) checkPushInReadOnly() ;
2207 pushNArray(x,(*n*4)) ;
feb7fa5d1e dngo*2208 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*2209 pushPopTraffic += *n*4 ;
2210 #endif
2211 }
2212
2213 void popbooleanarray_(char *x, int *n) {
2214 popNArray(x,(*n*4)) ;
2215 if (topRepetitionPoint) checkPopToReadOnly() ;
feb7fa5d1e dngo*2216 #ifdef ADSTACK_PROFILE
b4daa24319 Shre*2217 pushPopTraffic += *n*4 ;
2218 #endif
2219 }
2220
2221 void pushcharacter_(char* val) {
2222 pushCharacter(*val) ;
2223 }
2224
2225 void popcharacter_(char* val) {
2226 popCharacter(val) ;
2227 }
2228
2229 void pushreal4_(float* val) {
2230 pushReal4(*val) ;
2231 }
2232
2233 void popreal4_(float* val) {
2234 popReal4(val) ;
2235 }
2236
2237 void pushreal8_(double* val) {
2238 pushReal8(*val) ;
2239 }
2240
2241 void popreal8_(double* val) {
2242 popReal8(val) ;
2243 }
2244
feb7fa5d1e dngo*2245 void pushreal16_(long double *val) {
2246 pushReal16(val) ;
2247 }
2248
2249 void popreal16_(long double *val) {
2250 popReal16(val) ;
2251 }
2252
b4daa24319 Shre*2253 void pushinteger4_(int* val) {
2254 pushInteger4(*val) ;
2255 }
2256
2257 void popinteger4_(int* val) {
2258 popInteger4(val) ;
2259 }
2260
2261 void pushinteger8_(long* val) {
2262 pushInteger8(*val) ;
2263 }
2264
2265 void popinteger8_(long* val) {
2266 popInteger8(val) ;
2267 }
2268
2269 void pushcomplex8_(ccmplx* val) {
2270 pushComplex8(*val) ;
2271 }
2272
2273 void popcomplex8_(ccmplx* val) {
2274 popComplex8(val) ;
2275 }
2276
2277 void pushcomplex16_(cdcmplx *val) {
2278 pushComplex16(*((double complex *)val)) ;
2279 }
2280
2281 void popcomplex16_(cdcmplx* val) {
2282 popComplex16((double complex *)val) ;
2283 }
2284
2285 void pushpointer4_(void** val) {
2286 pushPointer4(*val) ;
2287 }
2288
2289 void poppointer4_(void** val) {
2290 popPointer4(val) ;
2291 }
2292
2293 void pushpointer8_(void** val) {
2294 pushPointer8(*val) ;
2295 }
2296
2297 void poppointer8_(void** val) {
2298 popPointer8(val) ;
2299 }
2300
2301 void pushcontrol1b_(int* cc) {
2302 pushControl1b(*cc) ;
2303 }
2304
2305 void popcontrol1b_(int *cc) {
2306 popControl1b(cc) ;
2307 }
2308
2309 void pushcontrol2b_(int *cc) {
2310 pushControl2b(*cc) ;
2311 }
2312
2313 void popcontrol2b_(int *cc) {
2314 popControl2b(cc) ;
2315 }
2316
2317 void pushcontrol3b_(int *cc) {
2318 pushControl3b(*cc) ;
2319 }
2320
2321 void popcontrol3b_(int *cc) {
2322 popControl3b(cc) ;
2323 }
2324
2325 void pushcontrol4b_(int *cc) {
2326 pushControl4b(*cc) ;
2327 }
2328
2329 void popcontrol4b_(int *cc) {
2330 popControl4b(cc) ;
2331 }
2332
2333 void pushcontrol5b_(int *cc) {
2334 pushControl5b(*cc) ;
2335 }
2336
2337 void popcontrol5b_(int *cc) {
2338 popControl5b(cc) ;
2339 }
2340
2341 void pushcontrol6b_(int *cc) {
2342 pushControl6b(*cc) ;
2343 }
2344
2345 void popcontrol6b_(int *cc) {
2346 popControl6b(cc) ;
2347 }
2348
2349 void pushcontrol7b_(int *cc) {
2350 pushControl7b(*cc) ;
2351 }
2352
2353 void popcontrol7b_(int *cc) {
2354 popControl7b(cc) ;
2355 }
2356
2357 void pushcontrol8b_(int *cc) {
2358 pushControl8b(*cc) ;
2359 }
2360
2361 void popcontrol8b_(int *cc) {
2362 popControl8b(cc) ;
2363 }
2364
feb7fa5d1e dngo*2365 void pushboolean_(int *x) {
2366 pushBoolean(*x) ;
2367 }
2368
2369 void popboolean_(int *x) {
2370 popBoolean(x) ;
2371 }
2372
b4daa24319 Shre*2373 void adstack_showpeaksize_() {
2374 adStack_showPeakSize() ;
2375 }
2376
2377 void adstack_showtotaltraffic_() {
2378 adStack_showTotalTraffic() ;
2379 }
2380
2381 void adstack_showstacksize_(int *label) {
2382 adStack_showStackSize(*label) ;
2383 }
2384
2385 void adstack_showstack_(char *locationName) {
2386 adStack_showStack(locationName) ;
2387 }
2388
feb7fa5d1e dngo*2389 int stackisthreadsafe_() {
2390 return stackIsThreadSafe() ;
b4daa24319 Shre*2391 }
2392
feb7fa5d1e dngo*2393 void showerrorcontext_() {
2394 showErrorContext() ;
2395 fflush(stdout) ;
b4daa24319 Shre*2396 }
2397
feb7fa5d1e dngo*2398 int locstrb_() {return (curStack ? curStack->rank : 0) ;}
2399 int locstro_() {return tappos;}