Back to home page

MITgcm

 
 

    


File indexing completed on 2023-05-28 05:10:56 UTC

view on githubraw file Latest commit b4daa243 on 2023-05-28 03:53:22 UTC
b4daa24319 Shre*0001 #include <stdlib.h>
                0002 #include <stdio.h>
                0003 #include <string.h>
                0004 #include "adStack.h"
                0005 
                0006 #include "adComplex.h"
                0007 
                0008 // Set to 0 to hide trace.
                0009 static int traceOn = 0 ;
                0010 static int freeemptyblocks = 1 ;
                0011 
                0012 char* pushBlock() ;
                0013 char* popBlock() ;
                0014 
                0015 /**************** block sizes for all data types *************/
                0016 
                0017 /* The size of a BLOCK in bytes. */
                0018 #define BLOCK_SIZE 65536
                0019 // #define BLOCK_SIZE 17 // A very small BLOCK_SIZE allows for stronger testing!
                0020 
                0021 /**************** data structures for stack ******************/
                0022 
                0023 /* The main stack is a double-chain of DoubleChainedBlock objects.
                0024  * Each DoubleChainedBlock holds an array[BLOCK_SIZE] of char. */
                0025 typedef struct _DoubleChainedBlock{
                0026   unsigned int rank ;
                0027   struct _DoubleChainedBlock *prev ;
                0028   struct _DoubleChainedBlock *next ;
                0029   char contents[BLOCK_SIZE] ;
                0030 } DoubleChainedBlock ;
                0031 
                0032 /** Structure keeping the needed info for ONE repetition level.
                0033  * As we can have "nested" repetition levels, these structures can be stacked. */
                0034 typedef struct _RepetitionLevel {
                0035   int hasBackPop ;
                0036   int active ;
                0037   DoubleChainedBlock* backPopBlock ;
                0038   int backPop ;
                0039   DoubleChainedBlock* resumePointBlock ;
                0040   int resumePoint ;
                0041   DoubleChainedBlock* freePushBlock ;
                0042   int freePush ;
                0043   unsigned int storedadbitbuf ;
                0044   int storedadbitibuf ;
                0045   struct _RepetitionLevel *previous ;
                0046 } RepetitionLevel ;
                0047 
                0048 /* A block and an integer to keep the current top in the block. When the block
                0049    is full, it is added to the double-chain list and a fresh block is used for
                0050    pushing. During popping, empty blocks are replenished with data from the
                0051    double-chain list. */
                0052 static int tappos  = BLOCK_SIZE ;
                0053 static char* tapblock = NULL ;
                0054 static DoubleChainedBlock *curStack = NULL ;
                0055 
                0056 /** The current stack of repetition levels. Initially empty */
                0057 RepetitionLevel *topRepetitionPoint = NULL ;
                0058 
                0059 /* Pushing single bits is different from the rest: we collect
                0060    32 bits in the integer below, before pushing that to the stack. */
                0061 static unsigned int adbitbuf = 0 ;
                0062 static int adbitibuf = 0 ;
                0063 
                0064 /** Accumulates the number of bytes pushed and popped */
                0065 static unsigned long long int pushPopTraffic = 0 ;
                0066 
                0067 /** Remembers the maximum number of stack Blocks used */
                0068 static long int maxBlocks = 0 ;
                0069 
                0070 //[llh] Don't know how to manage pushPopTraffic and maxBlocks in the OpenMP case ?
                0071 
                0072 /* All data structures must be threadprivate, so that each OpenMP thread has
                0073    its own stack. If the stack is compiled with OpenMP support and then used
                0074    in a program with no OpenMP parallel regions, the stack will work as
                0075    expected without using any extra resources. */
                0076 #pragma omp threadprivate(tappos, tapblock, curStack, adbitbuf, adbitibuf, topRepetitionPoint)
                0077 
                0078 /***************** repeated access mechanism *************/
                0079 
                0080 // Possible improvements:
                0081 //  - replace tappos with tapblock+tappos, saving a few "+" ?
                0082 //  - find a faster currentLocationStrictBelowFreePush and currentLocationEqualsFreePush
                0083 
                0084 // Notice: Algorithm for "nested" repetition level seems wrong (should be corrected)
                0085 //  when the deeper repetition level is started after new pushes.
                0086 
                0087 // We call "current location" the pair of
                0088 // (DoubleChainedBlock *) curStack // the current top stack block.
                0089 // (int) tappos                    // the offset of the current top in the current top stack block.
                0090 
                0091 void setBackPopToCurrentLocation(RepetitionLevel *repetitionLevel) {
                0092   repetitionLevel->hasBackPop = 1 ;
                0093   repetitionLevel->backPopBlock = curStack ;
                0094   repetitionLevel->backPop = tappos ;
                0095 }
                0096 
                0097 void setCurrentLocationToBackPop(RepetitionLevel *repetitionLevel) {
                0098   curStack = repetitionLevel->backPopBlock ;
                0099   tapblock = curStack->contents ;
                0100   tappos = repetitionLevel->backPop ;
                0101 }
                0102 
                0103 void setResumePointToCurrentLocation(RepetitionLevel *repetitionLevel) {
                0104   repetitionLevel->resumePointBlock = curStack ;
                0105   repetitionLevel->resumePoint = tappos ;
                0106 }
                0107 
                0108 void setCurrentLocationToResumePoint(RepetitionLevel *repetitionLevel) {
                0109   curStack = repetitionLevel->resumePointBlock ;
                0110   tapblock = curStack->contents ;
                0111   tappos = repetitionLevel->resumePoint ;
                0112 } 
                0113 
                0114 void setFreePushToCurrentLocation(RepetitionLevel *repetitionLevel) {
                0115   repetitionLevel->freePushBlock = curStack ;
                0116   repetitionLevel->freePush = tappos ;
                0117 }
                0118 
                0119 void setCurrentLocationToFreePush(RepetitionLevel *repetitionLevel) {
                0120   curStack = repetitionLevel->freePushBlock ;
                0121   tapblock = curStack->contents ;
                0122   tappos = repetitionLevel->freePush ;
                0123 } 
                0124 
                0125 //TODO: try inline this function for efficiency:
                0126 int currentLocationStrictBelowFreePush(RepetitionLevel *repetitionLevel) {
                0127   //[llh] I'd prefer to test directly on curStack->rank and tappos directly,
                0128   // but it's hard because N;BLOCK_SIZE <=> N+1;0 and both happen due to initial NULL curStack...
                0129   long int curL = (curStack->rank -1)*BLOCK_SIZE + tappos ;
                0130   long int fpL = (repetitionLevel->freePushBlock->rank -1)*BLOCK_SIZE + repetitionLevel->freePush ;
                0131   return (curL<fpL) ;
                0132 }
                0133 
                0134 //TODO: try inline this function for efficiency:
                0135 int currentLocationEqualsFreePush(RepetitionLevel *repetitionLevel) {
                0136   //[llh] I'd prefer to test directly on curStack->rank and tappos directly,
                0137   // but it's hard because N;BLOCK_SIZE <=> N+1;0 and both happen due to initial NULL curStack...
                0138   long int curL = (curStack->rank -1)*BLOCK_SIZE + tappos ;
                0139   long int fpL = (repetitionLevel->freePushBlock->rank -1)*BLOCK_SIZE + repetitionLevel->freePush ;
                0140   return (curL==fpL) ;
                0141 }
                0142 
                0143 void showLocation(DoubleChainedBlock *locBlock, int loc) {
                0144   printf("%1i.%05i", (locBlock ? locBlock->rank : 0), loc) ;
                0145 }
                0146 
                0147 void showRepetitionLevels() {
                0148   RepetitionLevel *repetitionPoint = topRepetitionPoint ;
                0149   while (repetitionPoint) {
                0150     printf("  REPETITION LEVEL ACTIVE:%i BP?%i", repetitionPoint->active, repetitionPoint->hasBackPop) ;
                0151     printf(" BP:") ; showLocation(repetitionPoint->backPopBlock, repetitionPoint->backPop) ;
                0152     printf(" RP:") ; showLocation(repetitionPoint->resumePointBlock, repetitionPoint->resumePoint) ;
                0153     printf(" FP:") ; showLocation(repetitionPoint->freePushBlock, repetitionPoint->freePush) ;
                0154     printf("\n") ;
                0155     repetitionPoint = repetitionPoint->previous ;
                0156     if (repetitionPoint) printf("  ...in") ;
                0157   }
                0158 }
                0159 
                0160 int locstrb_() {return (curStack ? curStack->rank : 0) ;}
                0161 int locstro_() {return tappos;}
                0162 
                0163 /** If we are in a protected, read-only section,
                0164  * memorize current location as "backPop" and go to the "freePush" location */
                0165 void checkPushInReadOnly() {
                0166   RepetitionLevel *topActive = topRepetitionPoint ;
                0167   while (topActive && !topActive->active) {
                0168     topActive = topActive->previous ;
                0169   }
                0170   if (topActive && currentLocationStrictBelowFreePush(topActive)) {
                0171     setBackPopToCurrentLocation(topActive) ;
                0172     setCurrentLocationToFreePush(topActive) ;
                0173     if (traceOn) {
                0174       printf("BEFORE PUSH AT ") ;
                0175       showLocation(topRepetitionPoint->backPopBlock, topRepetitionPoint->backPop) ;
                0176       printf("  WITH REPETITION LEVELS:\n") ;
                0177       showRepetitionLevels() ;
                0178       printf("  MOVE TO FREE PUSH LOCATION ") ;
                0179       showLocation(topRepetitionPoint->freePushBlock, topRepetitionPoint->freePush) ;
                0180       printf("\n") ;
                0181     }
                0182   }
                0183 }
                0184 
                0185 /** If current location is some "freePush" location,
                0186  * go back to its "backPop" location, which is in a protected, read-only section */
                0187 void checkPopToReadOnly() {
                0188   RepetitionLevel *repetitionPoint = topRepetitionPoint ;
                0189   int moves = (repetitionPoint->hasBackPop && currentLocationEqualsFreePush(repetitionPoint)) ;
                0190   if (traceOn && moves) {
                0191     printf("AFTER POP, LOCATION WAS ") ;
                0192     showLocation(curStack, tappos) ;
                0193     printf("  WITH REPETITION LEVELS:\n") ;
                0194     showRepetitionLevels() ;
                0195   }
                0196   int canEraseInactive = 1 ;
                0197   int canRemoveBackPop = 1 ;
                0198   do {
                0199     RepetitionLevel *oldCell = repetitionPoint ;
                0200     if (oldCell->hasBackPop && oldCell->active && currentLocationEqualsFreePush(oldCell)) {
                0201       setCurrentLocationToBackPop(oldCell) ;
                0202       if (canRemoveBackPop) oldCell->hasBackPop = 0 ;
                0203     }
                0204     repetitionPoint = oldCell->previous ;
                0205     if (!oldCell->active && canEraseInactive) {
                0206       free(oldCell) ;
                0207       topRepetitionPoint = repetitionPoint ;
                0208     } else {
                0209       canEraseInactive = 0 ;
                0210       canRemoveBackPop = 0 ;
                0211     }
                0212   } while (repetitionPoint) ;
                0213   if (traceOn && moves) {
                0214     printf("  MOVED TO BACK POP LOCATION:") ;
                0215     showLocation(curStack, tappos) ;
                0216     printf("\n") ;
                0217   }
                0218 }
                0219 
                0220 /** From now on, and until the matching closing adStack_endRepeat(),
                0221  * the current contents of the push-pop stack are preserved:
                0222  * Even if they are popped, any subsequent adStack_resetRepeat()
                0223  * will reset the push-pop stack to its current contents of now. */
                0224 void adStack_startRepeat() {
                0225   if (traceOn) {
                0226     printf("BEFORE START REPEAT AT ") ;
                0227     showLocation(curStack, tappos) ;
                0228     printf("\n") ;
                0229     showRepetitionLevels() ;
                0230   }
                0231   // Create a new repetition level and push it onto topRepetitionPoint
                0232   RepetitionLevel *newRepetitionLevel = (RepetitionLevel *)malloc(sizeof(RepetitionLevel)) ;
                0233   newRepetitionLevel->previous = topRepetitionPoint ;
                0234   newRepetitionLevel->hasBackPop = 0 ;
                0235   newRepetitionLevel->active = 1 ;
                0236   // Copy the bits buffer:
                0237   newRepetitionLevel->storedadbitbuf = adbitbuf ;
                0238   newRepetitionLevel->storedadbitibuf = adbitibuf ;
                0239   // In the very weird case where current stack is empty, make it explicit:
                0240   if (curStack==NULL) {
                0241     tapblock = pushBlock() ;
                0242     tappos = 0 ;
                0243   }
                0244   // Store current location as the "resumePoint" location:
                0245   setResumePointToCurrentLocation(newRepetitionLevel) ;
                0246   // Set the "freePush" location to current location OR to
                0247   // the "freePush" of the "enclosing" repetition level,
                0248   // (if there is one and it is higher)
                0249   if (topRepetitionPoint && currentLocationStrictBelowFreePush(topRepetitionPoint)) {
                0250     newRepetitionLevel->freePushBlock = topRepetitionPoint->freePushBlock ;
                0251     newRepetitionLevel->freePush = topRepetitionPoint->freePush ;
                0252   } else {
                0253     setFreePushToCurrentLocation(newRepetitionLevel) ;
                0254   }
                0255   // Make this new repetition level the current repetition level:
                0256   topRepetitionPoint = newRepetitionLevel ;
                0257   if (traceOn) {
                0258     printf(">AFTER START REPEAT AT:") ;
                0259     showLocation(curStack, tappos) ;
                0260     printf("\n") ;
                0261     showRepetitionLevels() ;
                0262   }
                0263 }
                0264 
                0265 /** Reset the push-pop stack contents to its contents at
                0266  * the time of the latest adStack_startRepeat() that has not been
                0267  * closed by a subsequent adStack_endRepeat() */
                0268 void adStack_resetRepeat() {
                0269   if (traceOn) {
                0270     printf("BEFORE RESET REPEAT AT ") ;
                0271     showLocation(curStack, tappos) ;
                0272     printf("\n") ;
                0273     showRepetitionLevels() ;
                0274   }
                0275   // Remove (pop) all passive deeper repetition levels:
                0276   while (topRepetitionPoint && !topRepetitionPoint->active) {
                0277     RepetitionLevel *oldTop = topRepetitionPoint ;
                0278     topRepetitionPoint = topRepetitionPoint->previous ;
                0279     free(oldTop) ;
                0280   }
                0281   // Reset current location to "resumePoint" location:
                0282   setCurrentLocationToResumePoint(topRepetitionPoint) ;
                0283   // Reset the bits buffer:
                0284   adbitbuf = topRepetitionPoint->storedadbitbuf ;
                0285   adbitibuf = topRepetitionPoint->storedadbitibuf ;
                0286   if (traceOn) {
                0287     printf(">AFTER RESET REPEAT AT ") ;
                0288     showLocation(curStack, tappos) ;
                0289     printf("\n") ;
                0290     showRepetitionLevels() ;
                0291   }
                0292 }
                0293 
                0294 /** Close (i.e. remove) the repetition level created by the latest adStack_startRepeat(). */
                0295 void adStack_endRepeat() {
                0296   if (traceOn) {
                0297     printf("BEFORE END REPEAT AT ") ;
                0298     showLocation(curStack, tappos) ;
                0299     printf("\n") ;
                0300     showRepetitionLevels() ;
                0301   }
                0302   // Set to inactive the topmost active repetition level:
                0303   RepetitionLevel *topActive = topRepetitionPoint ;
                0304   while (!topActive->active) {
                0305     topActive = topActive->previous ;
                0306   }
                0307   topActive->active = 0 ;
                0308   // current location may have moved back ; check if we must move further back:
                0309   if (topRepetitionPoint) checkPopToReadOnly() ;
                0310   if (traceOn) {
                0311     printf(">AFTER END REPEAT AT ") ;
                0312     showLocation(curStack, tappos) ;
                0313     printf("\n") ;
                0314     showRepetitionLevels() ;
                0315   }
                0316 }
                0317 
                0318 /***************** double-linked list management *************/
                0319 
                0320 /** add a data block to the double-linked list */
                0321 char* pushBlock() {
                0322   if (curStack && curStack->next) {
                0323     curStack = curStack->next ;
                0324   } else {
                0325     DoubleChainedBlock *newStack = (DoubleChainedBlock*)malloc(sizeof(DoubleChainedBlock)) ;
                0326     if (newStack == NULL) {
                0327       /* We ran out of memory, print an error message and give up. */
                0328       printf("Out of memory in AD Stack.\n") ;
                0329       exit(0) ;
                0330     }
                0331     if(curStack != NULL) {
                0332       curStack->next = newStack ;
                0333       newStack->rank = curStack->rank + 1 ;
                0334     } else {
                0335       newStack->rank = 1 ;
                0336     }
                0337 
                0338     newStack->prev = curStack ;
                0339     newStack->next = NULL ;
                0340     curStack = newStack ;
                0341   }
                0342 #ifdef _ADSTACKPROFILE
                0343   if (curStack->rank > maxBlocks) maxBlocks = curStack->rank ;
                0344 #endif
                0345   return curStack->contents ;
                0346 }
                0347 
                0348 /** retrieve a data block from the double-linked list */
                0349 char* popBlock() {
                0350   DoubleChainedBlock *oldTopStack = curStack ;
                0351   curStack = curStack->prev ;
                0352   if (freeemptyblocks) {
                0353     // Not necessary. Only needed if we want to free when the stack goes down:
                0354     // We must not free if we are in a repetition level and below its freePush point.
                0355     if (!(topRepetitionPoint && oldTopStack->rank <= topRepetitionPoint->freePushBlock->rank)) {
                0356       free(oldTopStack) ;
                0357       if (curStack) curStack->next = NULL ;
                0358     }
                0359     // end "Not necessary"
                0360   }
                0361   return (curStack ? curStack->contents : NULL) ;
                0362 }
                0363 
                0364 /********************* push/pop arrays ***********************/
                0365 
                0366 /* pushNArray/popNArray are used not only to store arrays of various data
                0367    types. These functions are also the only ones that interact with the dynamic
                0368    memory management, e.g. requesting new blocks. If one of the scalar push/pop
                0369    functions (e.g. pushReal4) encounters the end of a block, it will ask
                0370    pushNArray to do all the work, i.e. start a new block and push the real4
                0371    value to it. */
                0372 void pushNArray(char *x, int nbChars) {
                0373   do {
                0374     int wsize = tappos+nbChars<BLOCK_SIZE?nbChars:BLOCK_SIZE-tappos ;
                0375     if(wsize > 0) {
                0376       memcpy(tapblock+tappos,x,wsize) ;
                0377       nbChars -= wsize ;
                0378       x += wsize ;
                0379       tappos += wsize ;
                0380     }
                0381     else if (nbChars > 0) {
                0382       tapblock = pushBlock() ;
                0383       tappos = 0 ;
                0384     }
                0385   } while(nbChars > 0) ; //=> lazy push: if finishes at the top of block contents, does not push a new block.
                0386 }
                0387 
                0388 void popNArray(char *x, int nbChars) {
                0389   x += nbChars ;
                0390   do {
                0391     int wsize = (nbChars<tappos)?nbChars:tappos ;
                0392     if(wsize > 0) {
                0393       memcpy(x-wsize,tapblock+tappos-wsize,wsize) ;
                0394       nbChars -= wsize ;
                0395       x -= wsize ;
                0396       tappos -= wsize ;
                0397     }
                0398     else if (nbChars > 0) {
                0399       tapblock = popBlock() ;
                0400       tappos = BLOCK_SIZE ;
                0401     }
                0402   } while(nbChars > 0) ; //=> lazy pop: if finishes at the bottom of block contents, does not pop block.
                0403 }
                0404 
                0405 void pushInteger4Array(int *x, int n) {
                0406   if (topRepetitionPoint) checkPushInReadOnly() ;
                0407   pushNArray((char *)x,(int)(n*4)) ;
                0408 #ifdef _ADSTACKPROFILE
                0409   pushPopTraffic += (int)(n*4) ;
                0410 #endif
                0411 }
                0412 
                0413 void popInteger4Array(int *x, int n) {
                0414   popNArray((char *)x,(int)(n*4)) ;
                0415   if (topRepetitionPoint) checkPopToReadOnly() ;
                0416 #ifdef _ADSTACKPROFILE
                0417   pushPopTraffic += (int)(n*4) ;
                0418 #endif
                0419 }
                0420 
                0421 void pushInteger8Array(long *x, int n) {
                0422   if (topRepetitionPoint) checkPushInReadOnly() ;
                0423   pushNArray((char *)x,(int)(n*8)) ;
                0424 #ifdef _ADSTACKPROFILE
                0425   pushPopTraffic += (int)(n*8) ;
                0426 #endif
                0427 }
                0428 
                0429 void popInteger8Array(long *x, int n) {
                0430   popNArray((char *)x,(int)(n*8)) ;
                0431   if (topRepetitionPoint) checkPopToReadOnly() ;
                0432 #ifdef _ADSTACKPROFILE
                0433   pushPopTraffic += (int)(n*8) ;
                0434 #endif
                0435 }
                0436 
                0437 void pushReal4Array(float *x, int n) {
                0438   if (topRepetitionPoint) checkPushInReadOnly() ;
                0439   pushNArray((char *)x,(int)(n*4)) ;
                0440 #ifdef _ADSTACKPROFILE
                0441   pushPopTraffic += (int)(n*4) ;
                0442 #endif
                0443 }
                0444 
                0445 void popReal4Array(float *x, int n) {
                0446   popNArray((char *)x,(int)(n*4)) ;
                0447   if (topRepetitionPoint) checkPopToReadOnly() ;
                0448 #ifdef _ADSTACKPROFILE
                0449   pushPopTraffic += (int)(n*4) ;
                0450 #endif
                0451 }
                0452 
                0453 void pushReal8Array(double *x, int n) {
                0454   if (topRepetitionPoint) checkPushInReadOnly() ;
                0455   pushNArray((char *)x,(int)(n*8)) ;
                0456 #ifdef _ADSTACKPROFILE
                0457   pushPopTraffic += (int)(n*8) ;
                0458 #endif
                0459 }
                0460 
                0461 void popReal8Array(double *x, int n) {
                0462   popNArray((char *)x,(int)(n*8)) ;
                0463   if (topRepetitionPoint) checkPopToReadOnly() ;
                0464 #ifdef _ADSTACKPROFILE
                0465   pushPopTraffic += (int)(n*8) ;
                0466 #endif
                0467 }
                0468 
                0469 void pushComplex8Array(ccmplx *x, int n) {
                0470   if (topRepetitionPoint) checkPushInReadOnly() ;
                0471   pushNArray((char *)x,(int)(n*8)) ;
                0472 #ifdef _ADSTACKPROFILE
                0473   pushPopTraffic += (int)(n*8) ;
                0474 #endif
                0475 }
                0476 
                0477 void popComplex8Array(ccmplx *x, int n) {
                0478   popNArray((char *)x,(int)(n*8)) ;
                0479   if (topRepetitionPoint) checkPopToReadOnly() ;
                0480 #ifdef _ADSTACKPROFILE
                0481   pushPopTraffic += (int)(n*8) ;
                0482 #endif
                0483 }
                0484 
                0485 void pushComplex16Array(double complex *x, int n) {
                0486   if (topRepetitionPoint) checkPushInReadOnly() ;
                0487   pushNArray((char *)x,(int)(n*16)) ;
                0488 #ifdef _ADSTACKPROFILE
                0489   pushPopTraffic += (int)(n*16) ;
                0490 #endif
                0491 }
                0492 
                0493 void popComplex16Array(double complex *x, int n) {
                0494   popNArray((char *)x,(int)(n*16)) ;
                0495   if (topRepetitionPoint) checkPopToReadOnly() ;
                0496 #ifdef _ADSTACKPROFILE
                0497   pushPopTraffic += (int)(n*16) ;
                0498 #endif
                0499 }
                0500 
                0501 void pushCharacterArray(char *x, int n) {
                0502   if (topRepetitionPoint) checkPushInReadOnly() ;
                0503   pushNArray(x,(int)n) ;
                0504 #ifdef _ADSTACKPROFILE
                0505   pushPopTraffic += (int)n ;
                0506 #endif
                0507 }
                0508 
                0509 void popCharacterArray(char *x, int n) {
                0510   popNArray(x,(int)n) ;
                0511   if (topRepetitionPoint) checkPopToReadOnly() ;
                0512 #ifdef _ADSTACKPROFILE
                0513   pushPopTraffic += (int)n ;
                0514 #endif
                0515 }
                0516 
                0517 /***************** scalar push/pop functions *****************/
                0518 
                0519 void pushCharacter(char val) {
                0520   if (topRepetitionPoint) checkPushInReadOnly() ;
                0521   if(tappos + 1 > BLOCK_SIZE) {
                0522     pushNArray((char*)&val, 1) ;
                0523   }
                0524   else {
                0525     *(char*)(tapblock+tappos) = val;
                0526     tappos = tappos + 1 ;
                0527   }
                0528 #ifdef _ADSTACKPROFILE
                0529   pushPopTraffic += 1 ;
                0530 #endif
                0531 }
                0532 
                0533 void popCharacter(char * val) {
                0534   if(tappos - 1 < 0) {
                0535     popNArray((char*)val, 1) ;
                0536   }
                0537   else {
                0538     tappos = tappos - 1 ;
                0539     *val = *(char*)(tapblock+tappos);
                0540   }
                0541   if (topRepetitionPoint) checkPopToReadOnly() ;
                0542 #ifdef _ADSTACKPROFILE
                0543   pushPopTraffic += 1 ;
                0544 #endif
                0545 }
                0546 
                0547 void pushReal4(float val) {
                0548   if (topRepetitionPoint) checkPushInReadOnly() ;
                0549   if(tappos + 4 > BLOCK_SIZE) {
                0550     pushNArray((char*)&val, 4) ;
                0551   }
                0552   else {
                0553     *(float*)(tapblock+tappos) = val;
                0554     tappos = tappos + 4 ;
                0555   }
                0556 #ifdef _ADSTACKPROFILE
                0557   pushPopTraffic += 4 ;
                0558 #endif
                0559 }
                0560 
                0561 void popReal4(float * val) {
                0562   if(tappos - 4 < 0) {
                0563     popNArray((char*)val, 4) ;
                0564   }
                0565   else {
                0566     tappos = tappos - 4 ;
                0567     *val = *(float*)(tapblock+tappos);
                0568   }
                0569   if (topRepetitionPoint) checkPopToReadOnly() ;
                0570 #ifdef _ADSTACKPROFILE
                0571   pushPopTraffic += 4 ;
                0572 #endif
                0573 }
                0574 
                0575 void pushReal8(double val) {
                0576   if (topRepetitionPoint) checkPushInReadOnly() ;
                0577   if(tappos + 8 > BLOCK_SIZE) {
                0578     pushNArray((char*)&val, 8) ;
                0579   }
                0580   else {
                0581     *(double*)(tapblock+tappos) = val;
                0582     tappos = tappos + 8 ;
                0583   }
                0584 #ifdef _ADSTACKPROFILE
                0585   pushPopTraffic += 8 ;
                0586 #endif
                0587 }
                0588 
                0589 void popReal8(double * val) {
                0590   if(tappos - 8 < 0) {
                0591     popNArray((char*)val, 8) ;
                0592   }
                0593   else {
                0594     tappos = tappos - 8 ;
                0595     *val = *(double*)(tapblock+tappos);
                0596   }
                0597   if (topRepetitionPoint) checkPopToReadOnly() ;
                0598 #ifdef _ADSTACKPROFILE
                0599   pushPopTraffic += 8 ;
                0600 #endif
                0601 }
                0602 
                0603 void pushInteger4(int val) {
                0604   if (topRepetitionPoint) checkPushInReadOnly() ;
                0605   if(tappos + 4 > BLOCK_SIZE) {
                0606     pushNArray((char*)&val, 4) ;
                0607   }
                0608   else {
                0609     *(int*)(tapblock+tappos) = val;
                0610     tappos = tappos + 4 ;
                0611   }
                0612 #ifdef _ADSTACKPROFILE
                0613   pushPopTraffic += 4 ;
                0614 #endif
                0615 }
                0616 
                0617 void popInteger4(int * val) {
                0618   if(tappos - 4 < 0) {
                0619     popNArray((char*)val, 4) ;
                0620   }
                0621   else {
                0622     tappos = tappos - 4 ;
                0623     *val = *(int*)(tapblock+tappos);
                0624   }
                0625   if (topRepetitionPoint) checkPopToReadOnly() ;
                0626 #ifdef _ADSTACKPROFILE
                0627   pushPopTraffic += 4 ;
                0628 #endif
                0629 }
                0630 
                0631 void pushInteger8(long val) {
                0632   if (topRepetitionPoint) checkPushInReadOnly() ;
                0633   if(tappos + 8 > BLOCK_SIZE) {
                0634     pushNArray((char*)&val, 8) ;
                0635   }
                0636   else {
                0637     *(long*)(tapblock+tappos) = val;
                0638     tappos = tappos + 8 ;
                0639   }
                0640 #ifdef _ADSTACKPROFILE
                0641   pushPopTraffic += 8 ;
                0642 #endif
                0643 }
                0644 
                0645 void popInteger8(long * val) {
                0646   if(tappos - 8 < 0) {
                0647     popNArray((char*)val, 8) ;
                0648   }
                0649   else {
                0650     tappos = tappos - 8 ;
                0651     *val = *(long*)(tapblock+tappos);
                0652   }
                0653   if (topRepetitionPoint) checkPopToReadOnly() ;
                0654 #ifdef _ADSTACKPROFILE
                0655   pushPopTraffic += 8 ;
                0656 #endif
                0657 }
                0658 
                0659 void pushComplex8(ccmplx val) {
                0660   if (topRepetitionPoint) checkPushInReadOnly() ;
                0661   if(tappos + 8 > BLOCK_SIZE) {
                0662     pushNArray((char*)&val, 8) ;
                0663   }
                0664   else {
                0665     *(ccmplx*)(tapblock+tappos) = val;
                0666     tappos = tappos + 8 ;
                0667   }
                0668 #ifdef _ADSTACKPROFILE
                0669   pushPopTraffic += 8 ;
                0670 #endif
                0671 }
                0672 
                0673 void popComplex8(ccmplx * val) {
                0674   if(tappos - 8 < 0) {
                0675     popNArray((char*)val, 8) ;
                0676   }
                0677   else {
                0678     tappos = tappos - 8 ;
                0679     *val = *(ccmplx*)(tapblock+tappos);
                0680   }
                0681   if (topRepetitionPoint) checkPopToReadOnly() ;
                0682 #ifdef _ADSTACKPROFILE
                0683   pushPopTraffic += 8 ;
                0684 #endif
                0685 }
                0686 
                0687 void pushComplex16(double complex val) {
                0688   if (topRepetitionPoint) checkPushInReadOnly() ;
                0689   if(tappos + 16 > BLOCK_SIZE) {
                0690     pushNArray((char*)&val, 16) ;
                0691   }
                0692   else {
                0693     *(double complex *)(tapblock+tappos) = val;
                0694     tappos = tappos + 16 ;
                0695   }
                0696 #ifdef _ADSTACKPROFILE
                0697   pushPopTraffic += 16 ;
                0698 #endif
                0699 }
                0700 
                0701 void popComplex16(double complex *val) {
                0702   if(tappos - 16 < 0) {
                0703     popNArray((char*)val, 16) ;
                0704   }
                0705   else {
                0706     tappos = tappos - 16 ;
                0707     *val = *(double complex *)(tapblock+tappos);
                0708   }
                0709   if (topRepetitionPoint) checkPopToReadOnly() ;
                0710 #ifdef _ADSTACKPROFILE
                0711   pushPopTraffic += 16 ;
                0712 #endif
                0713 }
                0714 
                0715 void pushPointer4(void * val) {
                0716   if (topRepetitionPoint) checkPushInReadOnly() ;
                0717   if(tappos + 4 > BLOCK_SIZE) {
                0718     pushNArray((char*)&val, 4) ;
                0719   }
                0720   else {
                0721     *(void**)(tapblock+tappos) = val;
                0722     tappos = tappos + 4 ;
                0723   }
                0724 #ifdef _ADSTACKPROFILE
                0725   pushPopTraffic += 4 ;
                0726 #endif
                0727 }
                0728 
                0729 void popPointer4(void ** val) {
                0730   if(tappos - 4 < 0) {
                0731     popNArray((char*)val, 4) ;
                0732   }
                0733   else {
                0734     tappos = tappos - 4 ;
                0735     *val = *(void**)(tapblock+tappos);
                0736   }
                0737   if (topRepetitionPoint) checkPopToReadOnly() ;
                0738 #ifdef _ADSTACKPROFILE
                0739   pushPopTraffic += 4 ;
                0740 #endif
                0741 }
                0742 
                0743 void pushPointer8(void * val) {
                0744   if (topRepetitionPoint) checkPushInReadOnly() ;
                0745   if(tappos + 8 > BLOCK_SIZE) {
                0746     pushNArray((char*)&val, 8) ;
                0747   }
                0748   else {
                0749     *(void**)(tapblock+tappos) = val;
                0750     tappos = tappos + 8 ;
                0751   }
                0752 #ifdef _ADSTACKPROFILE
                0753   pushPopTraffic += 8 ;
                0754 #endif
                0755 }
                0756 
                0757 void popPointer8(void ** val) {
                0758   if(tappos - 8 < 0) {
                0759     popNArray((char*)val, 8) ;
                0760   }
                0761   else {
                0762     tappos = tappos - 8 ;
                0763     *val = *(void**)(tapblock+tappos);
                0764   }
                0765   if (topRepetitionPoint) checkPopToReadOnly() ;
                0766 #ifdef _ADSTACKPROFILE
                0767   pushPopTraffic += 8 ;
                0768 #endif
                0769 }
                0770 
                0771 /******************* bit (hidden primitives) ***************/
                0772 
                0773 void pushBit(int x) {
                0774   adbitbuf<<=1 ;
                0775   if (x) ++adbitbuf ;
                0776   if (adbitibuf>=31) {
                0777     pushNArray((char *)&adbitbuf, 4) ;
                0778     adbitbuf = 0 ;
                0779     adbitibuf = 0 ;
                0780 #ifdef _ADSTACKPROFILE
                0781     pushPopTraffic += 4 ;
                0782 #endif
                0783   } else
                0784     ++adbitibuf ;
                0785 }
                0786 
                0787 int popBit() {
                0788   if (adbitibuf<=0) {
                0789     popNArray((char *)&adbitbuf, 4) ;
                0790     adbitibuf = 31 ;
                0791 #ifdef _ADSTACKPROFILE
                0792     pushPopTraffic += 4 ;
                0793 #endif
                0794   } else
                0795     --adbitibuf ;
                0796   int result = adbitbuf%2 ;
                0797   adbitbuf>>=1 ;
                0798   return result ;
                0799 }
                0800 
                0801 /*************************** boolean *************************/
                0802 
                0803 void pushBoolean(int x) {
                0804   if (topRepetitionPoint) checkPushInReadOnly() ;
                0805   pushBit(x) ;
                0806 }
                0807 
                0808 //[llh] I have a bug here: the boolean returned to Fortran is bizarre!
                0809 void popBoolean(int *x) {
                0810   *x = popBit() ;
                0811   if (topRepetitionPoint) checkPopToReadOnly() ;
                0812 }
                0813 
                0814 /************************* control ***********************/
                0815 
                0816 void pushControl1b(int cc) {
                0817   if (topRepetitionPoint) checkPushInReadOnly() ;
                0818   pushBit(cc) ;
                0819 }
                0820 
                0821 void popControl1b(int *cc) {
                0822   *cc = popBit() ;
                0823   if (topRepetitionPoint) checkPopToReadOnly() ;
                0824 }
                0825 
                0826 void pushControl2b(int cc) {
                0827   if (topRepetitionPoint) checkPushInReadOnly() ;
                0828   pushBit(cc%2) ;
                0829   cc>>=1 ;
                0830   pushBit(cc) ;
                0831 }
                0832 
                0833 void popControl2b(int *cc) {
                0834   *cc = (popBit()?2:0) ;
                0835   if (popBit()) (*cc)++ ;
                0836   if (topRepetitionPoint) checkPopToReadOnly() ;
                0837 }
                0838 
                0839 void pushControl3b(int cc) {
                0840   if (topRepetitionPoint) checkPushInReadOnly() ;
                0841   pushBit(cc%2) ;
                0842   cc>>=1 ;
                0843   pushBit(cc%2) ;
                0844   cc>>=1 ;
                0845   pushBit(cc) ;
                0846 }
                0847 
                0848 void popControl3b(int *cc) {
                0849   *cc = (popBit()?2:0) ;
                0850   if (popBit()) (*cc)++ ;
                0851   (*cc) <<= 1 ;
                0852   if (popBit()) (*cc)++ ;
                0853   if (topRepetitionPoint) checkPopToReadOnly() ;
                0854 }
                0855 
                0856 void pushControl4b(int cc) {
                0857   if (topRepetitionPoint) checkPushInReadOnly() ;
                0858   pushBit(cc%2) ;
                0859   cc>>=1 ;
                0860   pushBit(cc%2) ;
                0861   cc>>=1 ;
                0862   pushBit(cc%2) ;
                0863   cc>>=1 ;
                0864   pushBit(cc) ;
                0865 }
                0866 
                0867 void popControl4b(int *cc) {
                0868   *cc = (popBit()?2:0) ;
                0869   if (popBit()) (*cc)++ ;
                0870   (*cc) <<= 1 ;
                0871   if (popBit()) (*cc)++ ;
                0872   (*cc) <<= 1 ;
                0873   if (popBit()) (*cc)++ ;
                0874   if (topRepetitionPoint) checkPopToReadOnly() ;
                0875 }
                0876 
                0877 void pushControl5b(int cc) {
                0878   if (topRepetitionPoint) checkPushInReadOnly() ;
                0879   pushBit(cc%2) ;
                0880   cc>>=1 ;
                0881   pushBit(cc%2) ;
                0882   cc>>=1 ;
                0883   pushBit(cc%2) ;
                0884   cc>>=1 ;
                0885   pushBit(cc%2) ;
                0886   cc>>=1 ;
                0887   pushBit(cc) ;
                0888 }
                0889 
                0890 void popControl5b(int *cc) {
                0891   *cc = (popBit()?2:0) ;
                0892   if (popBit()) (*cc)++ ;
                0893   (*cc) <<= 1 ;
                0894   if (popBit()) (*cc)++ ;
                0895   (*cc) <<= 1 ;
                0896   if (popBit()) (*cc)++ ;
                0897   (*cc) <<= 1 ;
                0898   if (popBit()) (*cc)++ ;
                0899   if (topRepetitionPoint) checkPopToReadOnly() ;
                0900 }
                0901 
                0902 void pushControl6b(int cc) {
                0903   if (topRepetitionPoint) checkPushInReadOnly() ;
                0904   pushBit(cc%2) ;
                0905   cc>>=1 ;
                0906   pushBit(cc%2) ;
                0907   cc>>=1 ;
                0908   pushBit(cc%2) ;
                0909   cc>>=1 ;
                0910   pushBit(cc%2) ;
                0911   cc>>=1 ;
                0912   pushBit(cc%2) ;
                0913   cc>>=1 ;
                0914   pushBit(cc) ;
                0915 }
                0916 
                0917 void popControl6b(int *cc) {
                0918   *cc = (popBit()?2:0) ;
                0919   if (popBit()) (*cc)++ ;
                0920   (*cc) <<= 1 ;
                0921   if (popBit()) (*cc)++ ;
                0922   (*cc) <<= 1 ;
                0923   if (popBit()) (*cc)++ ;
                0924   (*cc) <<= 1 ;
                0925   if (popBit()) (*cc)++ ;
                0926   (*cc) <<= 1 ;
                0927   if (popBit()) (*cc)++ ;
                0928   if (topRepetitionPoint) checkPopToReadOnly() ;
                0929 }
                0930 
                0931 void pushControl7b(int cc) {
                0932   if (topRepetitionPoint) checkPushInReadOnly() ;
                0933   pushBit(cc%2) ;
                0934   cc>>=1 ;
                0935   pushBit(cc%2) ;
                0936   cc>>=1 ;
                0937   pushBit(cc%2) ;
                0938   cc>>=1 ;
                0939   pushBit(cc%2) ;
                0940   cc>>=1 ;
                0941   pushBit(cc%2) ;
                0942   cc>>=1 ;
                0943   pushBit(cc%2) ;
                0944   cc>>=1 ;
                0945   pushBit(cc) ;
                0946 }
                0947 
                0948 void popControl7b(int *cc) {
                0949   *cc = (popBit()?2:0) ;
                0950   if (popBit()) (*cc)++ ;
                0951   (*cc) <<= 1 ;
                0952   if (popBit()) (*cc)++ ;
                0953   (*cc) <<= 1 ;
                0954   if (popBit()) (*cc)++ ;
                0955   (*cc) <<= 1 ;
                0956   if (popBit()) (*cc)++ ;
                0957   (*cc) <<= 1 ;
                0958   if (popBit()) (*cc)++ ;
                0959   (*cc) <<= 1 ;
                0960   if (popBit()) (*cc)++ ;
                0961   if (topRepetitionPoint) checkPopToReadOnly() ;
                0962 }
                0963 
                0964 void pushControl8b(int cc) {
                0965   if (topRepetitionPoint) checkPushInReadOnly() ;
                0966   pushBit(cc%2) ;
                0967   cc>>=1 ;
                0968   pushBit(cc%2) ;
                0969   cc>>=1 ;
                0970   pushBit(cc%2) ;
                0971   cc>>=1 ;
                0972   pushBit(cc%2) ;
                0973   cc>>=1 ;
                0974   pushBit(cc%2) ;
                0975   cc>>=1 ;
                0976   pushBit(cc%2) ;
                0977   cc>>=1 ;
                0978   pushBit(cc%2) ;
                0979   cc>>=1 ;
                0980   pushBit(cc) ;
                0981 }
                0982 
                0983 void popControl8b(int *cc) {
                0984   *cc = (popBit()?2:0) ;
                0985   if (popBit()) (*cc)++ ;
                0986   (*cc) <<= 1 ;
                0987   if (popBit()) (*cc)++ ;
                0988   (*cc) <<= 1 ;
                0989   if (popBit()) (*cc)++ ;
                0990   (*cc) <<= 1 ;
                0991   if (popBit()) (*cc)++ ;
                0992   (*cc) <<= 1 ;
                0993   if (popBit()) (*cc)++ ;
                0994   (*cc) <<= 1 ;
                0995   if (popBit()) (*cc)++ ;
                0996   (*cc) <<= 1 ;
                0997   if (popBit()) (*cc)++ ;
                0998   if (topRepetitionPoint) checkPopToReadOnly() ;
                0999 }
                1000 
                1001 /****************** Profiling and debugging *******************/
                1002 
                1003 void adStack_showPeakSize() {
                1004   printf("Peak stack size (%1li blocks): %1llu bytes\n",
                1005          maxBlocks, maxBlocks*((long long int)BLOCK_SIZE)) ;
                1006 }
                1007 
                1008 void adStack_showTotalTraffic() {
                1009   printf("Total push/pop traffic %1llu bytes\n", pushPopTraffic) ;
                1010 }
                1011 
                1012 void adStack_showStackSize(int label) {
                1013   printf(" %i--> <",label) ;
                1014   showLocation(curStack, tappos) ;
                1015   printf(">") ;
                1016 }
                1017 
                1018 void adStack_showStack(char *locationName) {
                1019   if (!curStack || (tappos==0 && !curStack->prev)) {
                1020     printf ("Stack at %s is empty\n", locationName) ;
                1021   } else {
                1022     printf ("Stack top at %s is %1i.%05i :\n", locationName, curStack->rank, tappos) ;
                1023     int bytesToShow = 20 ;
                1024     int blocksToShow = 3 ;
                1025     DoubleChainedBlock *inStack = curStack ;
                1026     int inPos = tappos ;
                1027     while (blocksToShow>0 && inStack) {
                1028       printf("  Block %d:", inStack->rank) ;
                1029       while (bytesToShow>0 && inPos>0) {
                1030         printf(" %02x", (unsigned char)inStack->contents[--inPos]) ;
                1031         --bytesToShow ;
                1032       }
                1033       if (inPos>0)
                1034         printf(" ...<%d more bytes>...", inPos) ;
                1035       printf(" |\n") ;
                1036       --blocksToShow ;
                1037       inStack = inStack->prev ;
                1038       inPos = BLOCK_SIZE ;
                1039     }
                1040     if (inStack)
                1041       printf("  %d more blocks below\n", inStack->rank) ;
                1042   }
                1043   if (adbitibuf==0) {
                1044     printf("Bit buffer is empty\n") ;
                1045   } else {
                1046     printf("Bit buffer:%1i in %08x\n", adbitibuf, adbitbuf) ;
                1047   }
                1048   if (topRepetitionPoint) {
                1049     printf("Repetition levels:\n  ") ;
                1050     showRepetitionLevels() ;
                1051   }
                1052   printf("----------------\n") ;
                1053 }
                1054 
                1055 /******* query if this stack was compiled with OpenMP ******/
                1056 int stackIsThreadSafe() {
                1057   #ifdef _OPENMP
                1058     return 1 ;
                1059   #else
                1060     return 0 ;
                1061   #endif
                1062 }
                1063 
                1064 /****************** INTERFACE CALLED FROM FORTRAN *******************/
                1065 
                1066 void adstack_startrepeat_() {
                1067   adStack_startRepeat() ;
                1068 }
                1069 
                1070 void adstack_resetrepeat_() {
                1071   adStack_resetRepeat() ;
                1072 }
                1073 
                1074 void adstack_endrepeat_() {
                1075   adStack_endRepeat() ;
                1076 }
                1077 
                1078 void pushinteger4array_(int *ii, int *ll) {
                1079   pushInteger4Array(ii, *ll) ;
                1080 }
                1081 
                1082 void popinteger4array_(int *ii, int *ll) {
                1083   popInteger4Array(ii, *ll) ;
                1084 }
                1085 
                1086 void pushinteger8array_(long *ii, int *ll) {
                1087   pushInteger8Array(ii, *ll) ;
                1088 }
                1089 
                1090 void popinteger8array_(long *ii, int *ll) {
                1091   popInteger8Array(ii, *ll) ;
                1092 }
                1093 
                1094 void pushreal4array_(float *ii, int *ll) {
                1095   pushReal4Array(ii, *ll) ;
                1096 }
                1097 
                1098 void popreal4array_(float *ii, int *ll) {
                1099   popReal4Array(ii, *ll) ;
                1100 }
                1101 
                1102 void pushreal8array_(double *ii, int *ll) {
                1103   pushReal8Array(ii, *ll) ;
                1104 }
                1105 
                1106 void popreal8array_(double *ii, int *ll) {
                1107   popReal8Array(ii, *ll) ;
                1108 }
                1109 
                1110 void pushcomplex8array_(ccmplx *ii, int *ll) {
                1111   pushComplex8Array(ii, *ll) ;
                1112 }
                1113 
                1114 void popcomplex8array_(ccmplx *ii, int *ll) {
                1115   popComplex8Array(ii, *ll) ;
                1116 }
                1117 
                1118 void pushcomplex16array_(cdcmplx *ii, int *ll) {
                1119   pushComplex16Array((double complex *)ii, *ll) ;
                1120 }
                1121 
                1122 void popcomplex16array_(cdcmplx *ii, int *ll) {
                1123   popComplex16Array((double complex *)ii, *ll) ;
                1124 }
                1125 
                1126 void pushcharacterarray_(char *ii, int *ll) {
                1127   pushCharacterArray(ii, *ll) ;
                1128 }
                1129 
                1130 void popcharacterarray_(char *ii, int *ll) {
                1131   popCharacterArray(ii, *ll) ;
                1132 }
                1133 
                1134 void pushbooleanarray_(char *x, int *n) {
                1135   if (topRepetitionPoint) checkPushInReadOnly() ;
                1136   pushNArray(x,(*n*4)) ;
                1137 #ifdef _ADSTACKPROFILE
                1138   pushPopTraffic += *n*4 ;
                1139 #endif
                1140 }
                1141 
                1142 void popbooleanarray_(char *x, int *n) {
                1143   popNArray(x,(*n*4)) ;
                1144   if (topRepetitionPoint) checkPopToReadOnly() ;
                1145 #ifdef _ADSTACKPROFILE
                1146   pushPopTraffic += *n*4 ;
                1147 #endif
                1148 }
                1149 
                1150 void pushcharacter_(char* val) {
                1151   pushCharacter(*val) ;
                1152 }
                1153 
                1154 void popcharacter_(char* val) {
                1155   popCharacter(val) ;
                1156 }
                1157 
                1158 void pushreal4_(float* val) {
                1159   pushReal4(*val) ;
                1160 }
                1161 
                1162 void popreal4_(float* val) {
                1163   popReal4(val) ;
                1164 }
                1165 
                1166 void pushreal8_(double* val) {
                1167   pushReal8(*val) ;
                1168 }
                1169 
                1170 void popreal8_(double* val) {
                1171   popReal8(val) ;
                1172 }
                1173 
                1174 void pushinteger4_(int* val) {
                1175   pushInteger4(*val) ;
                1176 }
                1177 
                1178 void popinteger4_(int* val) {
                1179   popInteger4(val) ;
                1180 }
                1181 
                1182 void pushinteger8_(long* val) {
                1183   pushInteger8(*val) ;
                1184 }
                1185 
                1186 void popinteger8_(long* val) {
                1187   popInteger8(val) ;
                1188 }
                1189 
                1190 void pushcomplex8_(ccmplx* val) {
                1191   pushComplex8(*val) ;
                1192 }
                1193 
                1194 void popcomplex8_(ccmplx* val) {
                1195   popComplex8(val) ;
                1196 }
                1197 
                1198 void pushcomplex16_(cdcmplx *val) {
                1199   pushComplex16(*((double complex *)val)) ;
                1200 }
                1201 
                1202 void popcomplex16_(cdcmplx* val) {
                1203   popComplex16((double complex *)val) ;
                1204 }
                1205 
                1206 void pushpointer4_(void** val) {
                1207   pushPointer4(*val) ;
                1208 }
                1209 
                1210 void poppointer4_(void** val) {
                1211   popPointer4(val) ;
                1212 }
                1213 
                1214 void pushpointer8_(void** val) {
                1215   pushPointer8(*val) ;
                1216 }
                1217 
                1218 void poppointer8_(void** val) {
                1219   popPointer8(val) ;
                1220 }
                1221 
                1222 void pushcontrol1b_(int* cc) {
                1223   pushControl1b(*cc) ;
                1224 }
                1225 
                1226 void popcontrol1b_(int *cc) {
                1227   popControl1b(cc) ;
                1228 }
                1229 
                1230 void pushcontrol2b_(int *cc) {
                1231   pushControl2b(*cc) ;
                1232 }
                1233 
                1234 void popcontrol2b_(int *cc) {
                1235   popControl2b(cc) ;
                1236 }
                1237 
                1238 void pushcontrol3b_(int *cc) {
                1239   pushControl3b(*cc) ;
                1240 }
                1241 
                1242 void popcontrol3b_(int *cc) {
                1243   popControl3b(cc) ;
                1244 }
                1245 
                1246 void pushcontrol4b_(int *cc) {
                1247   pushControl4b(*cc) ;
                1248 }
                1249 
                1250 void popcontrol4b_(int *cc) {
                1251   popControl4b(cc) ;
                1252 }
                1253 
                1254 void pushcontrol5b_(int *cc) {
                1255   pushControl5b(*cc) ;
                1256 }
                1257 
                1258 void popcontrol5b_(int *cc) {
                1259   popControl5b(cc) ;
                1260 }
                1261 
                1262 void pushcontrol6b_(int *cc) {
                1263   pushControl6b(*cc) ;
                1264 }
                1265 
                1266 void popcontrol6b_(int *cc) {
                1267   popControl6b(cc) ;
                1268 }
                1269 
                1270 void pushcontrol7b_(int *cc) {
                1271   pushControl7b(*cc) ;
                1272 }
                1273 
                1274 void popcontrol7b_(int *cc) {
                1275   popControl7b(cc) ;
                1276 }
                1277 
                1278 void pushcontrol8b_(int *cc) {
                1279   pushControl8b(*cc) ;
                1280 }
                1281 
                1282 void popcontrol8b_(int *cc) {
                1283   popControl8b(cc) ;
                1284 }
                1285 
                1286 void adstack_showpeaksize_() {
                1287   adStack_showPeakSize() ;
                1288 }
                1289 
                1290 void adstack_showtotaltraffic_() {
                1291   adStack_showTotalTraffic() ;
                1292 }
                1293 
                1294 void adstack_showstacksize_(int *label) {
                1295   adStack_showStackSize(*label) ;
                1296 }
                1297 
                1298 void adstack_showstack_(char *locationName) {
                1299   adStack_showStack(locationName) ;
                1300 }
                1301 
                1302 void pushboolean_(int *x) {
                1303   pushBoolean(*x) ;
                1304 }
                1305 
                1306 void popboolean_(int *x) {
                1307   popBoolean(x) ;
                1308 }
                1309 
                1310 int stackisthreadsafe_() {
                1311   return stackIsThreadSafe() ;
                1312 }