FORM 4.3
checkpoint.c
Go to the documentation of this file.
1/*
2 #[ Explanations :
3*/
52/*
53 #] Explanations :
54 #[ License :
55 *
56 * Copyright (C) 1984-2022 J.A.M. Vermaseren
57 * When using this file you are requested to refer to the publication
58 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
59 * This is considered a matter of courtesy as the development was paid
60 * for by FOM the Dutch physics granting agency and we would like to
61 * be able to track its scientific use to convince FOM of its value
62 * for the community.
63 *
64 * This file is part of FORM.
65 *
66 * FORM is free software: you can redistribute it and/or modify it under the
67 * terms of the GNU General Public License as published by the Free Software
68 * Foundation, either version 3 of the License, or (at your option) any later
69 * version.
70 *
71 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
72 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
73 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
74 * details.
75 *
76 * You should have received a copy of the GNU General Public License along
77 * with FORM. If not, see <http://www.gnu.org/licenses/>.
78 */
79/*
80 #] License :
81 #[ Includes :
82*/
83
84#include "form3.h"
85
86#include <errno.h>
87
88/*
89#define PRINTDEBUG
90*/
91
92/*
93#define PRINTTIMEMARKS
94*/
95
96/*
97 #] Includes :
98 #[ filenames and system commands :
99*/
100
104#ifdef WITHMPI
105#define BASENAME_FMT "%c%04dFORMrecv"
111static char BaseName[] = BASENAME_FMT;
112#else
113static char *BaseName = "FORMrecv";
114#endif
118static char *recoveryfile = 0;
124static char *intermedfile = 0;
128static char *sortfile = 0;
132static char *hidefile = 0;
136static char *storefile = 0;
137
142static int done_snapshot = 0;
143
144#ifdef WITHMPI
149static int PF_fmt_pos;
150
155static const char *PF_recoveryfile(char prefix, int id, int intermed)
156{
157 /*
158 * Assume that InitRecovery() has been already called, namely
159 * recoveryfile, intermedfile and PF_fmt_pos are already initialized.
160 */
161 static char *tmp_recovery = NULL;
162 static char *tmp_intermed = NULL;
163 char *tmp, c;
164 if ( tmp_recovery == NULL ) {
165 if ( PF.numtasks > 9999 ) { /* see BASENAME_FMT */
166 MesPrint("Checkpoint: too many number of processors.");
167 Terminate(-1);
168 }
169 tmp_recovery = (char *)Malloc1(strlen(recoveryfile) + strlen(intermedfile) + 2, "PF_recoveryfile");
170 tmp_intermed = tmp_recovery + strlen(recoveryfile) + 1;
171 strcpy(tmp_recovery, recoveryfile);
172 strcpy(tmp_intermed, intermedfile);
173 }
174 tmp = intermed ? tmp_intermed : tmp_recovery;
175 c = tmp[PF_fmt_pos + 13]; /* The magic number 13 comes from BASENAME_FMT. */
176 sprintf(tmp + PF_fmt_pos, BASENAME_FMT, prefix, id);
177 tmp[PF_fmt_pos + 13] = c;
178 return tmp;
179}
180#endif
181
182/*
183 #] filenames and system commands :
184 #[ CheckRecoveryFile :
185*/
186
191#ifdef WITHMPI
192
198static int PF_CheckRecoveryFile()
199{
200 int i,ret=0;
201 FILE *fd;
202 /* Check if the recovery file for the master exists. */
203 if ( PF.me == MASTER ) {
204 if ( (fd = fopen(recoveryfile, "r")) ) {
205 fclose(fd);
207 }
208 else {
210 return 0;
211 }
212 }
213 else {
214 if ( !PF_BroadcastNumber(0) )
215 return 0;
216 }
217 /* Now the main part. */
218 if (PF.me == MASTER){
219 /*We have to have recovery files for the master and all the slaves:*/
220 for(i=1; i<PF.numtasks;i++){
221 const char *tmpnam = PF_recoveryfile('m', i, 0);
222 if ( (fd = fopen(tmpnam, "r")) )
223 fclose(fd);
224 else
225 break;
226 }/*for(i=0; i<PF.numtasks;i++)*/
227 if(i!=PF.numtasks){/*some files are absent*/
228 int j;
229 /*Send all slaves failure*/
230 for(j=1; j<PF.numtasks;j++){
231 ret=PF_SendFile(j, NULL);
232 if(ret<0)
233 return(-1);
234 }
235 if(i==0)
236 return(0);/*Ok, no recovery files at all.*/
237 /*The master recovery file exists but some slave files are absent*/
238 MesPrint("The file %s exists but some of the slave recovery files are absent.",
240 return(-1);
241 }/*if(i!=PF.numtasks)*/
242 /*All the files are here.*/
243 /*Send all slaves success and files:*/
244 for(i=1; i<PF.numtasks;i++){
245 const char *tmpnam = PF_recoveryfile('m', i, 0);
246 fd = fopen(tmpnam, "r");
247 ret=PF_SendFile(i, fd);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
248 if(fd == NULL)
249 return(-1);
250 else
251 fclose(fd);
252 if(ret<0)
253 return(-1);
254 }/*for(i=0; i<PF.numtasks;i++)*/
255 return(1);
256 }/*if (PF.me == MASTER)*/
257 /*Slave:*/
258 /*Get the answer from the master:*/
259 fd=fopen(recoveryfile,"w");
260 if(fd == NULL) {
261 MesPrint("Failed to open %s in write mode in process %w", recoveryfile);
262 return(-1);
263 }
264 ret=PF_RecvFile(MASTER,fd);
265 if(ret<0)
266 return(-1);
267 fclose(fd);
268 if(ret==0){
269 /*Nothing is found by the master*/
270 remove(recoveryfile);
271 return(0);
272 }
273 /*Recovery file is successfully transferred*/
274 return(1);
275}
276#endif
277
279{
280 int ret = 0;
281#ifdef WITHMPI
282 ret = PF_CheckRecoveryFile();
283#else
284 FILE *fd;
285 if ( (fd = fopen(recoveryfile, "r")) ) {
286 fclose(fd);
287 ret = 1;
288 }
289#endif
290 if ( ret < 0 ){/*In ParFORM CheckRecoveryFile() may return a fatal error.*/
291 MesPrint("Fail checking recovery file");
292 Terminate(-1);
293 }
294 else if ( ret > 0 ) {
295 if ( AC.CheckpointFlag != -1 ) {
296 /* recovery file exists but recovery option is not given */
297#ifdef WITHMPI
298 if ( PF.me == MASTER ) {
299#endif
300 MesPrint("The recovery file %s exists, but the recovery option -R has not been given!", RecoveryFilename());
301 MesPrint("FORM will be terminated to avoid unintentional loss of data.");
302 MesPrint("Delete the recovery file manually, if you want to start FORM without recovery.");
303#ifdef WITHMPI
304 }
305 if(PF.me != MASTER)
306 remove(RecoveryFilename());
307#endif
308 Terminate(-1);
309 }
310 }
311 else {
312 if ( AC.CheckpointFlag == -1 ) {
313 /* recovery option given but recovery file does not exist */
314#ifdef WITHMPI
315 if ( PF.me == MASTER )
316#endif
317 MesPrint("Option -R for recovery has been given, but the recovery file %s does not exist!", RecoveryFilename());
318 Terminate(-1);
319 }
320 }
321 return(ret);
322}
323
324/*
325 #] CheckRecoveryFile :
326 #[ DeleteRecoveryFile :
327*/
328
334{
335 if ( done_snapshot ) {
336 remove(recoveryfile);
337#ifdef WITHMPI
338 if( PF.me == MASTER){
339 int i;
340 for(i=1; i<PF.numtasks;i++){
341 const char *tmpnam = PF_recoveryfile('m', i, 0);
342 remove(tmpnam);
343 }/*for(i=1; i<PF.numtasks;i++)*/
344 remove(storefile);
345 remove(sortfile);
346 remove(hidefile);
347 }/*if( PF.me == MASTER)*/
348#else
349 remove(storefile);
350 remove(sortfile);
351 remove(hidefile);
352#endif
353 }
354}
355
356/*
357 #] DeleteRecoveryFile :
358 #[ RecoveryFilename :
359*/
360
365{
366 return(recoveryfile);
367}
368
369/*
370 #] RecoveryFilename :
371 #[ InitRecovery :
372*/
373
377static char *InitName(char *str, char *ext)
378{
379 char *s, *d = str;
380 if ( AM.TempDir ) {
381 s = (char*)AM.TempDir;
382 while ( *s ) { *d++ = *s++; }
383 *d++ = SEPARATOR;
384 }
385 s = BaseName;
386 while ( *s ) { *d++ = *s++; }
387 *d++ = '.';
388 s = ext;
389 while ( *s ) { *d++ = *s++; }
390 *d++ = 0;
391 return d;
392}
393
400{
401 int lenpath = AM.TempDir ? strlen((char*)AM.TempDir)+1 : 0;
402#ifdef WITHMPI
403 sprintf(BaseName,BASENAME_FMT,(PF.me == MASTER)?'m':'s',PF.me);
404 /*Now BaseName has a form ?XXXXFORMrecv where ? == 'm' for master and 's' for slave,
405 XXXX is a zero - padded PF.me*/
406 PF_fmt_pos = lenpath;
407#endif
408 recoveryfile = (char*)Malloc1(5*(lenpath+strlen(BaseName)+4+1),"InitRecovery");
409 intermedfile = InitName(recoveryfile, "tmp");
410 sortfile = InitName(intermedfile, "XXX");
411 hidefile = InitName(sortfile, "out");
412 storefile = InitName(hidefile, "hid");
413 InitName(storefile, "str");
414}
415
416/*
417 #] InitRecovery :
418 #[ Debugging :
419*/
420
421#ifdef PRINTDEBUG
422
423void print_BYTE(void *p)
424{
425 UBYTE h = (UBYTE)(*((UBYTE*)p) >> 4);
426 UBYTE l = (UBYTE)(*((UBYTE*)p) & 0x0F);
427 if ( h > 9 ) h += 55; else h += 48;
428 if ( l > 9 ) l += 55; else l += 48;
429 printf("%c%c ", h, l);
430}
431
432static void print_STR(UBYTE *p)
433{
434 if ( p ) {
435 MesPrint("%s", (char*)p);
436 }
437 else {
438 MesPrint("NULL");
439 }
440}
441
442static void print_WORDB(WORD *buf, WORD *top)
443{
444 LONG size = top-buf;
445 int i;
446 while ( size > 0 ) {
447 if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
448 else i = size;
449 size -= i;
450 MesPrint("%a",i,buf);
451 buf += i;
452 }
453}
454
455static void print_VOIDP(void *p, size_t size)
456{
457 int i;
458 if ( p ) {
459 while ( size > 0 ) {
460 if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
461 else i = size;
462 size -= i;
463 MesPrint("%b",i,(UBYTE *)p);
464 p = ((UBYTE *)p)+i;
465 }
466 }
467 else {
468 MesPrint("NULL");
469 }
470}
471
472static void print_CHARS(UBYTE *p, size_t size)
473{
474 int i;
475 while ( size > 0 ) {
476 if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
477 else i = size;
478 size -= i;
479 MesPrint("%C",i,(char *)p);
480 p += i;
481 }
482}
483
484static void print_WORDV(WORD *p, size_t size)
485{
486 int i;
487 if ( p ) {
488 while ( size > 0 ) {
489 if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
490 else i = size;
491 size -= i;
492 MesPrint("%a",i,p);
493 p += i;
494 }
495 }
496 else {
497 MesPrint("NULL");
498 }
499}
500
501static void print_INTV(int *p, size_t size)
502{
503 int iarray[8];
504 WORD i = 0;
505 if ( p ) {
506 while ( size > 0 ) {
507 if ( i >= 8 ) {
508 MesPrint("%I",i,iarray);
509 i = 0;
510 }
511 iarray[i++] = *p++;
512 size--;
513 }
514 if ( i > 0 ) MesPrint("%I",i,iarray);
515 }
516 else {
517 MesPrint("NULL");
518 }
519}
520
521static void print_LONGV(LONG *p, size_t size)
522{
523 LONG larray[8];
524 WORD i = 0;
525 if ( p ) {
526 while ( size > 0 ) {
527 if ( i >= 8 ) {
528 MesPrint("%I",i,larray);
529 i = 0;
530 }
531 larray[i++] = *p++;
532 size--;
533 }
534 if ( i > 0 ) MesPrint("%I",i,larray);
535 }
536 else {
537 MesPrint("NULL");
538 }
539}
540
541static void print_PRELOAD(PRELOAD *l)
542{
543 if ( l->size ) {
544 print_CHARS(l->buffer, l->size);
545 }
546 MesPrint("%ld", l->size);
547}
548
549static void print_PREVAR(PREVAR *l)
550{
551 MesPrint("%s", l->name);
552 print_STR(l->value);
553 if ( l->nargs ) print_STR(l->argnames);
554 MesPrint("%d", l->nargs);
555 MesPrint("%d", l->wildarg);
556}
557
558static void print_DOLLARS(DOLLARS l)
559{
560 print_VOIDP(l->where, l->size);
561 MesPrint("%ld", l->size);
562 MesPrint("%ld", l->name);
563 MesPrint("%s", AC.dollarnames->namebuffer+l->name);
564 MesPrint("%d", l->type);
565 MesPrint("%d", l->node);
566 MesPrint("%d", l->index);
567 MesPrint("%d", l->zero);
568 MesPrint("%d", l->numdummies);
569 MesPrint("%d", l->nfactors);
570}
571
572static void print_LIST(LIST *l)
573{
574 print_VOIDP(l->lijst, l->size);
575 MesPrint("%s", l->message);
576 MesPrint("%d", l->num);
577 MesPrint("%d", l->maxnum);
578 MesPrint("%d", l->size);
579 MesPrint("%d", l->numglobal);
580 MesPrint("%d", l->numtemp);
581 MesPrint("%d", l->numclear);
582}
583
584static void print_DOLOOP(DOLOOP *l)
585{
586 print_PRELOAD(&(l->p));
587 print_STR(l->name);
588 if ( l->type != NUMERICALLOOP ) {
589 print_STR(l->vars);
590 }
591 print_STR(l->contents);
592 if ( l->type != LISTEDLOOP && l->type != NUMERICALLOOP ) {
593 print_STR(l->dollarname);
594 }
595 MesPrint("%l", l->startlinenumber);
596 MesPrint("%l", l->firstnum);
597 MesPrint("%l", l->lastnum);
598 MesPrint("%l", l->incnum);
599 MesPrint("%d", l->type);
600 MesPrint("%d", l->NoShowInput);
601 MesPrint("%d", l->errorsinloop);
602 MesPrint("%d", l->firstloopcall);
603}
604
605static void print_PROCEDURE(PROCEDURE *l)
606{
607 if ( l->loadmode != 1 ) {
608 print_PRELOAD(&(l->p));
609 }
610 print_STR(l->name);
611 MesPrint("%d", l->loadmode);
612}
613
614static void print_NAMETREE(NAMETREE *t)
615{
616 int i;
617 for ( i=0; i<t->nodefill; ++i ) {
618 MesPrint("%l %d %d %d %d %d %d\n", t->namenode[i].name,
619 t->namenode[i].parent, t->namenode[i].left, t->namenode[i].right,
620 t->namenode[i].balance, t->namenode[i].type, t->namenode[i].number );
621 }
622 print_CHARS(t->namebuffer, t->namefill);
623 MesPrint("%l", t->namesize);
624 MesPrint("%l", t->namefill);
625 MesPrint("%l", t->nodesize);
626 MesPrint("%l", t->nodefill);
627 MesPrint("%l", t->oldnamefill);
628 MesPrint("%l", t->oldnodefill);
629 MesPrint("%l", t->globalnamefill);
630 MesPrint("%l", t->globalnodefill);
631 MesPrint("%l", t->clearnamefill);
632 MesPrint("%l", t->clearnodefill);
633 MesPrint("%d", t->headnode);
634}
635
636void print_CBUF(CBUF *c)
637{
638 int i;
639 print_WORDV(c->Buffer, c->BufferSize);
640 /*
641 MesPrint("%x", c->Buffer);
642 MesPrint("%x", c->lhs);
643 MesPrint("%x", c->rhs);
644 */
645 for ( i=0; i<c->numlhs; ++i ) {
646 if ( c->lhs[i]) MesPrint("%d", *(c->lhs[i]));
647 }
648 for ( i=0; i<c->numrhs; ++i ) {
649 if ( c->rhs[i]) MesPrint("%d", *(c->rhs[i]));
650 }
651 MesPrint("%l", *c->CanCommu);
652 MesPrint("%l", *c->NumTerms);
653 MesPrint("%d", *c->numdum);
654 for ( i=0; i<c->MaxTreeSize; ++i ) {
655 MesPrint("%d %d %d %d %d", c->boomlijst[i].parent, c->boomlijst[i].left, c->boomlijst[i].right,
656 c->boomlijst[i].value, c->boomlijst[i].blnce);
657 }
658}
659
660static void print_STREAM(STREAM *t)
661{
662 print_CHARS(t->buffer, t->inbuffer);
663 MesPrint("%l", (LONG)(t->pointer-t->buffer));
664 print_STR(t->FoldName);
665 print_STR(t->name);
666 if ( t->type == PREVARSTREAM || t->type == DOLLARSTREAM ) {
667 print_STR(t->pname);
668 }
669 MesPrint("%l", (LONG)t->fileposition);
670 MesPrint("%l", (LONG)t->linenumber);
671 MesPrint("%l", (LONG)t->prevline);
672 MesPrint("%l", t->buffersize);
673 MesPrint("%l", t->bufferposition);
674 MesPrint("%l", t->inbuffer);
675 MesPrint("%d", t->previous);
676 MesPrint("%d", t->handle);
677 switch ( t->type ) {
678 case FILESTREAM: MesPrint("%d == FILESTREAM", t->type); break;
679 case PREVARSTREAM: MesPrint("%d == PREVARSTREAM", t->type); break;
680 case PREREADSTREAM: MesPrint("%d == PREREADSTREAM", t->type); break;
681 case PIPESTREAM: MesPrint("%d == PIPESTREAM", t->type); break;
682 case PRECALCSTREAM: MesPrint("%d == PRECALCSTREAM", t->type); break;
683 case DOLLARSTREAM: MesPrint("%d == DOLLARSTREAM", t->type); break;
684 case PREREADSTREAM2: MesPrint("%d == PREREADSTREAM2", t->type); break;
685 case EXTERNALCHANNELSTREAM: MesPrint("%d == EXTERNALCHANNELSTREAM", t->type); break;
686 case PREREADSTREAM3: MesPrint("%d == PREREADSTREAM3", t->type); break;
687 default: MesPrint("%d == UNKNOWN", t->type);
688 }
689}
690
691static void print_M()
692{
693 MesPrint("%%%% M_const");
694 MesPrint("%d", *AM.gcmod);
695 MesPrint("%d", *AM.gpowmod);
696 print_STR(AM.TempDir);
697 print_STR(AM.TempSortDir);
698 print_STR(AM.IncDir);
699 print_STR(AM.InputFileName);
700 print_STR(AM.LogFileName);
701 print_STR(AM.OutBuffer);
702 print_STR(AM.Path);
703 print_STR(AM.SetupDir);
704 print_STR(AM.SetupFile);
705 MesPrint("--MARK 1");
706 MesPrint("%l", (LONG)BASEPOSITION(AM.zeropos));
707#ifdef WITHPTHREADS
708 MesPrint("%l", AM.ThreadScratSize);
709 MesPrint("%l", AM.ThreadScratOutSize);
710#endif
711 MesPrint("%l", AM.MaxTer);
712 MesPrint("%l", AM.CompressSize);
713 MesPrint("%l", AM.ScratSize);
714 MesPrint("%l", AM.SizeStoreCache);
715 MesPrint("%l", AM.MaxStreamSize);
716 MesPrint("%l", AM.SIOsize);
717 MesPrint("%l", AM.SLargeSize);
718 MesPrint("%l", AM.SSmallEsize);
719 MesPrint("%l", AM.SSmallSize);
720 MesPrint("--MARK 2");
721 MesPrint("%l", AM.STermsInSmall);
722 MesPrint("%l", AM.MaxBracketBufferSize);
723 MesPrint("%l", AM.hProcessBucketSize);
724 MesPrint("%l", AM.gProcessBucketSize);
725 MesPrint("%l", AM.shmWinSize);
726 MesPrint("%l", AM.OldChildTime);
727 MesPrint("%l", AM.OldSecTime);
728 MesPrint("%l", AM.OldMilliTime);
729 MesPrint("%l", AM.WorkSize);
730 MesPrint("%l", AM.gThreadBucketSize);
731 MesPrint("--MARK 3");
732 MesPrint("%l", AM.ggThreadBucketSize);
733 MesPrint("%d", AM.FileOnlyFlag);
734 MesPrint("%d", AM.Interact);
735 MesPrint("%d", AM.MaxParLevel);
736 MesPrint("%d", AM.OutBufSize);
737 MesPrint("%d", AM.SMaxFpatches);
738 MesPrint("%d", AM.SMaxPatches);
739 MesPrint("%d", AM.StdOut);
740 MesPrint("%d", AM.ginsidefirst);
741 MesPrint("%d", AM.gDefDim);
742 MesPrint("%d", AM.gDefDim4);
743 MesPrint("--MARK 4");
744 MesPrint("%d", AM.NumFixedSets);
745 MesPrint("%d", AM.NumFixedFunctions);
746 MesPrint("%d", AM.rbufnum);
747 MesPrint("%d", AM.dbufnum);
748 MesPrint("%d", AM.SkipClears);
749 MesPrint("%d", AM.gfunpowers);
750 MesPrint("%d", AM.gStatsFlag);
751 MesPrint("%d", AM.gNamesFlag);
752 MesPrint("%d", AM.gCodesFlag);
753 MesPrint("%d", AM.gTokensWriteFlag);
754 MesPrint("%d", AM.gSortType);
755 MesPrint("%d", AM.gproperorderflag);
756 MesPrint("--MARK 5");
757 MesPrint("%d", AM.hparallelflag);
758 MesPrint("%d", AM.gparallelflag);
759 MesPrint("%d", AM.totalnumberofthreads);
760 MesPrint("%d", AM.gSizeCommuteInSet);
761 MesPrint("%d", AM.gThreadStats);
762 MesPrint("%d", AM.ggThreadStats);
763 MesPrint("%d", AM.gFinalStats);
764 MesPrint("%d", AM.ggFinalStats);
765 MesPrint("%d", AM.gThreadsFlag);
766 MesPrint("%d", AM.ggThreadsFlag);
767 MesPrint("%d", AM.gThreadBalancing);
768 MesPrint("%d", AM.ggThreadBalancing);
769 MesPrint("%d", AM.gThreadSortFileSynch);
770 MesPrint("%d", AM.ggThreadSortFileSynch);
771 MesPrint("%d", AM.gProcessStats);
772 MesPrint("%d", AM.ggProcessStats);
773 MesPrint("%d", AM.gOldParallelStats);
774 MesPrint("%d", AM.ggOldParallelStats);
775 MesPrint("%d", AM.gWTimeStatsFlag);
776 MesPrint("%d", AM.ggWTimeStatsFlag);
777 MesPrint("%d", AM.maxFlevels);
778 MesPrint("--MARK 6");
779 MesPrint("%d", AM.resetTimeOnClear);
780 MesPrint("%d", AM.gcNumDollars);
781 MesPrint("%d", AM.MultiRun);
782 MesPrint("%d", AM.gNoSpacesInNumbers);
783 MesPrint("%d", AM.ggNoSpacesInNumbers);
784 MesPrint("%d", AM.MaxTal);
785 MesPrint("%d", AM.IndDum);
786 MesPrint("%d", AM.DumInd);
787 MesPrint("%d", AM.WilInd);
788 MesPrint("%d", AM.gncmod);
789 MesPrint("%d", AM.gnpowmod);
790 MesPrint("%d", AM.gmodmode);
791 MesPrint("--MARK 7");
792 MesPrint("%d", AM.gUnitTrace);
793 MesPrint("%d", AM.gOutputMode);
794 MesPrint("%d", AM.gCnumpows);
795 MesPrint("%d", AM.gOutputSpaces);
796 MesPrint("%d", AM.gOutNumberType);
797 MesPrint("%d %d %d %d", AM.gUniTrace[0], AM.gUniTrace[1], AM.gUniTrace[2], AM.gUniTrace[3]);
798 MesPrint("%d", AM.MaxWildcards);
799 MesPrint("%d", AM.mTraceDum);
800 MesPrint("%d", AM.OffsetIndex);
801 MesPrint("%d", AM.OffsetVector);
802 MesPrint("%d", AM.RepMax);
803 MesPrint("%d", AM.LogType);
804 MesPrint("%d", AM.ggStatsFlag);
805 MesPrint("%d", AM.gLineLength);
806 MesPrint("%d", AM.qError);
807 MesPrint("--MARK 8");
808 MesPrint("%d", AM.FortranCont);
809 MesPrint("%d", AM.HoldFlag);
810 MesPrint("%d %d %d %d %d", AM.Ordering[0], AM.Ordering[1], AM.Ordering[2], AM.Ordering[3], AM.Ordering[4]);
811 MesPrint("%d %d %d %d %d", AM.Ordering[5], AM.Ordering[6], AM.Ordering[7], AM.Ordering[8], AM.Ordering[9]);
812 MesPrint("%d %d %d %d %d", AM.Ordering[10], AM.Ordering[11], AM.Ordering[12], AM.Ordering[13], AM.Ordering[14]);
813 MesPrint("%d", AM.silent);
814 MesPrint("%d", AM.tracebackflag);
815 MesPrint("%d", AM.expnum);
816 MesPrint("%d", AM.denomnum);
817 MesPrint("%d", AM.facnum);
818 MesPrint("%d", AM.invfacnum);
819 MesPrint("%d", AM.sumnum);
820 MesPrint("%d", AM.sumpnum);
821 MesPrint("--MARK 9");
822 MesPrint("%d", AM.OldOrderFlag);
823 MesPrint("%d", AM.termfunnum);
824 MesPrint("%d", AM.matchfunnum);
825 MesPrint("%d", AM.countfunnum);
826 MesPrint("%d", AM.gPolyFun);
827 MesPrint("%d", AM.gPolyFunInv);
828 MesPrint("%d", AM.gPolyFunType);
829 MesPrint("%d", AM.gPolyFunExp);
830 MesPrint("%d", AM.gPolyFunVar);
831 MesPrint("%d", AM.gPolyFunPow);
832 MesPrint("--MARK 10");
833 MesPrint("%d", AM.dollarzero);
834 MesPrint("%d", AM.atstartup);
835 MesPrint("%d", AM.exitflag);
836 MesPrint("%d", AM.NumStoreCaches);
837 MesPrint("%d", AM.gIndentSpace);
838 MesPrint("%d", AM.ggIndentSpace);
839 MesPrint("%d", AM.gShortStatsMax);
840 MesPrint("%d", AM.ggShortStatsMax);
841 MesPrint("--MARK 11");
842 MesPrint("%d", AM.FromStdin);
843 MesPrint("%%%% END M_const");
844/* fflush(0); */
845}
846
847static void print_P()
848{
849 int i;
850 MesPrint("%%%% P_const");
851 print_LIST(&AP.DollarList);
852 for ( i=0; i<AP.DollarList.num; ++i ) {
853 print_DOLLARS(&(Dollars[i]));
854 }
855 MesPrint("--MARK 1");
856 print_LIST(&AP.PreVarList);
857 for ( i=0; i<AP.PreVarList.num; ++i ) {
858 print_PREVAR(&(PreVar[i]));
859 }
860 MesPrint("--MARK 2");
861 print_LIST(&AP.LoopList);
862 for ( i=0; i<AP.LoopList.num; ++i ) {
863 print_DOLOOP(&(DoLoops[i]));
864 }
865 MesPrint("--MARK 3");
866 print_LIST(&AP.ProcList);
867 for ( i=0; i<AP.ProcList.num; ++i ) {
868 print_PROCEDURE(&(Procedures[i]));
869 }
870 MesPrint("--MARK 4");
871 for ( i=0; i<=AP.PreSwitchLevel; ++i ) {
872 print_STR(AP.PreSwitchStrings[i]);
873 }
874 MesPrint("%l", AP.preStop-AP.preStart);
875 if ( AP.preFill ) MesPrint("%l", AP.preFill-AP.preStart);
876 print_CHARS(AP.preStart, AP.pSize);
877 MesPrint("%s", AP.procedureExtension);
878 MesPrint("%s", AP.cprocedureExtension);
879 print_INTV(AP.PreIfStack, AP.MaxPreIfLevel);
880 print_INTV(AP.PreSwitchModes, AP.NumPreSwitchStrings+1);
881 print_INTV(AP.PreTypes, AP.NumPreTypes+1);
882 MesPrint("%d", AP.PreAssignFlag);
883 MesPrint("--MARK 5");
884 MesPrint("%d", AP.PreContinuation);
885 MesPrint("%l", AP.InOutBuf);
886 MesPrint("%l", AP.pSize);
887 MesPrint("%d", AP.PreproFlag);
888 MesPrint("%d", AP.iBufError);
889 MesPrint("%d", AP.PreOut);
890 MesPrint("%d", AP.PreSwitchLevel);
891 MesPrint("%d", AP.NumPreSwitchStrings);
892 MesPrint("%d", AP.MaxPreTypes);
893 MesPrint("--MARK 6");
894 MesPrint("%d", AP.NumPreTypes);
895 MesPrint("%d", AP.DelayPrevar);
896 MesPrint("%d", AP.AllowDelay);
897 MesPrint("%d", AP.lhdollarerror);
898 MesPrint("%d", AP.eat);
899 MesPrint("%d", AP.gNumPre);
900 MesPrint("%d", AP.PreDebug);
901 MesPrint("--MARK 7");
902 MesPrint("%d", AP.DebugFlag);
903 MesPrint("%d", AP.preError);
904 MesPrint("%C", 1, &(AP.ComChar));
905 MesPrint("%C", 1, &(AP.cComChar));
906 MesPrint("%%%% END P_const");
907/* fflush(0); */
908}
909
910static void print_C()
911{
912 int i;
913 UBYTE buf[40], *t;
914 MesPrint("%%%% C_const");
915 for ( i=0; i<32; ++i ) {
916 t = buf;
917 t = NumCopy((WORD)(AC.separators[i].bit_7),t);
918 t = NumCopy((WORD)(AC.separators[i].bit_6),t);
919 t = NumCopy((WORD)(AC.separators[i].bit_5),t);
920 t = NumCopy((WORD)(AC.separators[i].bit_4),t);
921 t = NumCopy((WORD)(AC.separators[i].bit_3),t);
922 t = NumCopy((WORD)(AC.separators[i].bit_2),t);
923 t = NumCopy((WORD)(AC.separators[i].bit_1),t);
924 t = NumCopy((WORD)(AC.separators[i].bit_0),t);
925 MesPrint("%s ",buf);
926 }
927 print_NAMETREE(AC.dollarnames);
928 print_NAMETREE(AC.exprnames);
929 print_NAMETREE(AC.varnames);
930 MesPrint("--MARK 1");
931 print_LIST(&AC.ChannelList);
932 for ( i=0; i<AC.ChannelList.num; ++i ) {
933 MesPrint("%s %d", channels[i].name, channels[i].handle);
934 }
935 MesPrint("--MARK 2");
936 print_LIST(&AC.DubiousList);
937 MesPrint("--MARK 3");
938 print_LIST(&AC.FunctionList);
939 for ( i=0; i<AC.FunctionList.num; ++i ) {
940 if ( functions[i].tabl ) {
941
942 }
943 MesPrint("%l", functions[i].symminfo);
944 MesPrint("%l", functions[i].name);
945 MesPrint("%d", functions[i].namesize);
946 }
947 MesPrint("--MARK 4");
948 print_LIST(&AC.ExpressionList);
949 print_LIST(&AC.IndexList);
950 print_LIST(&AC.SetElementList);
951 print_LIST(&AC.SetList);
952 MesPrint("--MARK 5");
953 print_LIST(&AC.SymbolList);
954 print_LIST(&AC.VectorList);
955 print_LIST(&AC.PotModDolList);
956 print_LIST(&AC.ModOptDolList);
957 print_LIST(&AC.TableBaseList);
958
959/*
960 print_LIST(&AC.cbufList);
961 for ( i=0; i<AC.cbufList.num; ++i ) {
962 MesPrint("cbufList.num == %d", i);
963 print_CBUF(cbuf+i);
964 }
965 MesPrint("%d", AC.cbufnum);
966*/
967 MesPrint("--MARK 6");
968
969 print_LIST(&AC.AutoSymbolList);
970 print_LIST(&AC.AutoIndexList);
971 print_LIST(&AC.AutoVectorList);
972 print_LIST(&AC.AutoFunctionList);
973
974 print_NAMETREE(AC.autonames);
975 MesPrint("--MARK 7");
976
977 print_LIST(AC.Symbols);
978 print_LIST(AC.Indices);
979 print_LIST(AC.Vectors);
980 print_LIST(AC.Functions);
981 MesPrint("--MARK 8");
982
983 print_NAMETREE(*AC.activenames);
984
985 MesPrint("--MARK 9");
986
987 MesPrint("%d", AC.AutoDeclareFlag);
988
989 for ( i=0; i<AC.NumStreams; ++i ) {
990 MesPrint("Stream %d\n", i);
991 print_STREAM(AC.Streams+i);
992 }
993 print_STREAM(AC.CurrentStream);
994 MesPrint("--MARK 10");
995
996 print_LONGV(AC.termstack, AC.maxtermlevel);
997 print_LONGV(AC.termsortstack, AC.maxtermlevel);
998 print_VOIDP(AC.cmod, AM.MaxTal*4*sizeof(UWORD));
999 print_WORDV((WORD *)(AC.cmod), 1);
1000 print_WORDV((WORD *)(AC.powmod), 1);
1001 print_WORDV((WORD*)AC.modpowers, 1);
1002 print_WORDV((WORD*)AC.halfmod, 1);
1003 MesPrint("--MARK 10-2");
1004 /*
1005 print_WORDV(AC.ProtoType, AC.ProtoType[1]);
1006 print_WORDV(AC.WildC, 1);
1007 */
1008
1009 MesPrint("--MARK 11");
1010 /* IfHeap ... Labels */
1011
1012 print_CHARS((UBYTE*)AC.tokens, AC.toptokens-AC.tokens);
1013 MesPrint("%l", AC.endoftokens-AC.tokens);
1014 print_WORDV(AC.tokenarglevel, AM.MaxParLevel);
1015 print_WORDV((WORD*)AC.modinverses, ABS(AC.ncmod));
1016#ifdef WITHPTHREADS
1017 print_LONGV(AC.inputnumbers, AC.sizepfirstnum+AC.sizepfirstnum*sizeof(WORD)/sizeof(LONG));
1018 print_WORDV(AC.pfirstnum, 1);
1019#endif
1020 MesPrint("--MARK 12");
1021 print_LONGV(AC.argstack, MAXNEST);
1022 print_LONGV(AC.insidestack, MAXNEST);
1023 print_LONGV(AC.inexprstack, MAXNEST);
1024 MesPrint("%l", AC.iBufferSize);
1025 MesPrint("%l", AC.TransEname);
1026 MesPrint("%l", AC.ProcessBucketSize);
1027 MesPrint("%l", AC.mProcessBucketSize);
1028 MesPrint("%l", AC.CModule);
1029 MesPrint("%l", AC.ThreadBucketSize);
1030 MesPrint("%d", AC.NoShowInput);
1031 MesPrint("%d", AC.ShortStats);
1032 MesPrint("%d", AC.compiletype);
1033 MesPrint("%d", AC.firstconstindex);
1034 MesPrint("%d", AC.insidefirst);
1035 MesPrint("%d", AC.minsidefirst);
1036 MesPrint("%d", AC.wildflag);
1037 MesPrint("%d", AC.NumLabels);
1038 MesPrint("%d", AC.MaxLabels);
1039 MesPrint("--MARK 13");
1040 MesPrint("%d", AC.lDefDim);
1041 MesPrint("%d", AC.lDefDim4);
1042 MesPrint("%d", AC.NumWildcardNames);
1043 MesPrint("%d", AC.WildcardBufferSize);
1044 MesPrint("%d", AC.MaxIf);
1045 MesPrint("%d", AC.NumStreams);
1046 MesPrint("%d", AC.MaxNumStreams);
1047 MesPrint("%d", AC.firstctypemessage);
1048 MesPrint("%d", AC.tablecheck);
1049 MesPrint("%d", AC.idoption);
1050 MesPrint("%d", AC.BottomLevel);
1051 MesPrint("%d", AC.CompileLevel);
1052 MesPrint("%d", AC.TokensWriteFlag);
1053 MesPrint("%d", AC.UnsureDollarMode);
1054 MesPrint("%d", AC.outsidefun);
1055 MesPrint("%d", AC.funpowers);
1056 MesPrint("--MARK 14");
1057 MesPrint("%d", AC.WarnFlag);
1058 MesPrint("%d", AC.StatsFlag);
1059 MesPrint("%d", AC.NamesFlag);
1060 MesPrint("%d", AC.CodesFlag);
1061 MesPrint("%d", AC.TokensWriteFlag);
1062 MesPrint("%d", AC.SetupFlag);
1063 MesPrint("%d", AC.SortType);
1064 MesPrint("%d", AC.lSortType);
1065 MesPrint("%d", AC.ThreadStats);
1066 MesPrint("%d", AC.FinalStats);
1067 MesPrint("%d", AC.ThreadsFlag);
1068 MesPrint("%d", AC.ThreadBalancing);
1069 MesPrint("%d", AC.ThreadSortFileSynch);
1070 MesPrint("%d", AC.ProcessStats);
1071 MesPrint("%d", AC.OldParallelStats);
1072 MesPrint("%d", AC.WTimeStatsFlag);
1073 MesPrint("%d", AC.BracketNormalize);
1074 MesPrint("%d", AC.maxtermlevel);
1075 MesPrint("%d", AC.dumnumflag);
1076 MesPrint("--MARK 15");
1077 MesPrint("%d", AC.bracketindexflag);
1078 MesPrint("%d", AC.parallelflag);
1079 MesPrint("%d", AC.mparallelflag);
1080 MesPrint("%d", AC.properorderflag);
1081 MesPrint("%d", AC.vetofilling);
1082 MesPrint("%d", AC.tablefilling);
1083 MesPrint("%d", AC.vetotablebasefill);
1084 MesPrint("%d", AC.exprfillwarning);
1085 MesPrint("%d", AC.lhdollarflag);
1086 MesPrint("%d", AC.NoCompress);
1087#ifdef WITHPTHREADS
1088 MesPrint("%d", AC.numpfirstnum);
1089 MesPrint("%d", AC.sizepfirstnum);
1090#endif
1091 MesPrint("%d", AC.RepLevel);
1092 MesPrint("%d", AC.arglevel);
1093 MesPrint("%d", AC.insidelevel);
1094 MesPrint("%d", AC.inexprlevel);
1095 MesPrint("%d", AC.termlevel);
1096 MesPrint("--MARK 16");
1097 print_WORDV(AC.argsumcheck, MAXNEST);
1098 print_WORDV(AC.insidesumcheck, MAXNEST);
1099 print_WORDV(AC.inexprsumcheck, MAXNEST);
1100 MesPrint("%d", AC.MustTestTable);
1101 MesPrint("%d", AC.DumNum);
1102 MesPrint("%d", AC.ncmod);
1103 MesPrint("%d", AC.npowmod);
1104 MesPrint("%d", AC.modmode);
1105 MesPrint("%d", AC.nhalfmod);
1106 MesPrint("%d", AC.DirtPow);
1107 MesPrint("%d", AC.lUnitTrace);
1108 MesPrint("%d", AC.NwildC);
1109 MesPrint("%d", AC.ComDefer);
1110 MesPrint("%d", AC.CollectFun);
1111 MesPrint("%d", AC.AltCollectFun);
1112 MesPrint("--MARK 17");
1113 MesPrint("%d", AC.OutputMode);
1114 MesPrint("%d", AC.Cnumpows);
1115 MesPrint("%d", AC.OutputSpaces);
1116 MesPrint("%d", AC.OutNumberType);
1117 print_WORDV(AC.lUniTrace, 4);
1118 print_WORDV(AC.RepSumCheck, MAXREPEAT);
1119 MesPrint("%d", AC.DidClean);
1120 MesPrint("%d", AC.IfLevel);
1121 MesPrint("%d", AC.WhileLevel);
1122 print_WORDV(AC.IfSumCheck, (AC.MaxIf+1));
1123 MesPrint("%d", AC.LogHandle);
1124 MesPrint("%d", AC.LineLength);
1125 MesPrint("%d", AC.StoreHandle);
1126 MesPrint("%d", AC.HideLevel);
1127 MesPrint("%d", AC.lPolyFun);
1128 MesPrint("%d", AC.lPolyFunInv);
1129 MesPrint("%d", AC.lPolyFunType);
1130 MesPrint("%d", AC.lPolyFunExp);
1131 MesPrint("%d", AC.lPolyFunVar);
1132 MesPrint("%d", AC.lPolyFunPow);
1133 MesPrint("%d", AC.SymChangeFlag);
1134 MesPrint("%d", AC.CollectPercentage);
1135 MesPrint("%d", AC.ShortStatsMax);
1136 MesPrint("--MARK 18");
1137
1138 print_CHARS(AC.Commercial, COMMERCIALSIZE+2);
1139
1140 MesPrint("%", AC.CheckpointFlag);
1141 MesPrint("%l", AC.CheckpointStamp);
1142 print_STR((unsigned char*)AC.CheckpointRunAfter);
1143 print_STR((unsigned char*)AC.CheckpointRunBefore);
1144 MesPrint("%l", AC.CheckpointInterval);
1145
1146 MesPrint("%%%% END C_const");
1147/* fflush(0); */
1148}
1149
1150static void print_R()
1151{
1152 GETIDENTITY
1153 int i;
1154 MesPrint("%%%% R_const");
1155 MesPrint("%l", (LONG)(AR.infile-AR.Fscr));
1156 MesPrint("%s", AR.infile->name);
1157 MesPrint("%l", (LONG)(AR.outfile-AR.Fscr));
1158 MesPrint("%s", AR.outfile->name);
1159 MesPrint("%l", AR.hidefile-AR.Fscr);
1160 MesPrint("%s", AR.hidefile->name);
1161 for ( i=0; i<3; ++i ) {
1162 MesPrint("FSCR %d", i);
1163 print_WORDB(AR.Fscr[i].PObuffer, AR.Fscr[i].POfull);
1164 }
1165 /* ... */
1166 MesPrint("%l", AR.OldTime);
1167 MesPrint("%l", AR.InInBuf);
1168 MesPrint("%l", AR.InHiBuf);
1169 MesPrint("%l", AR.pWorkSize);
1170 MesPrint("%l", AR.lWorkSize);
1171 MesPrint("%l", AR.posWorkSize);
1172 MesPrint("%d", AR.NoCompress);
1173 MesPrint("%d", AR.gzipCompress);
1174 MesPrint("%d", AR.Cnumlhs);
1175#ifdef WITHPTHREADS
1176 MesPrint("%d", AR.exprtodo);
1177#endif
1178 MesPrint("%d", AR.GetFile);
1179 MesPrint("%d", AR.KeptInHold);
1180 MesPrint("%d", AR.BracketOn);
1181 MesPrint("%d", AR.MaxBracket);
1182 MesPrint("%d", AR.CurDum);
1183 MesPrint("%d", AR.DeferFlag);
1184 MesPrint("%d", AR.TePos);
1185 MesPrint("%d", AR.sLevel);
1186 MesPrint("%d", AR.Stage4Name);
1187 MesPrint("%d", AR.GetOneFile);
1188 MesPrint("%d", AR.PolyFun);
1189 MesPrint("%d", AR.PolyFunInv);
1190 MesPrint("%d", AR.PolyFunType);
1191 MesPrint("%d", AR.PolyFunExp);
1192 MesPrint("%d", AR.PolyFunVar);
1193 MesPrint("%d", AR.PolyFunPow);
1194 MesPrint("%d", AR.Eside);
1195 MesPrint("%d", AR.MaxDum);
1196 MesPrint("%d", AR.level);
1197 MesPrint("%d", AR.expchanged);
1198 MesPrint("%d", AR.expflags);
1199 MesPrint("%d", AR.CurExpr);
1200 MesPrint("%d", AR.SortType);
1201 MesPrint("%d", AR.ShortSortCount);
1202 MesPrint("%%%% END R_const");
1203/* fflush(0); */
1204}
1205
1206#endif /* ifdef PRINTDEBUG */
1207
1208/*
1209 #] Debugging :
1210 #[ Cached file operation functions :
1211*/
1212
1213#define CACHED_SNAPSHOT
1214
1215#define CACHE_SIZE 4096
1216
1217#ifdef CACHED_SNAPSHOT
1218unsigned char cache_buffer[CACHE_SIZE];
1219size_t cache_fill = 0;
1220
1221size_t fwrite_cached(const void *ptr, size_t size, size_t nmemb, FILE *fd)
1222{
1223 size_t fullsize = size*nmemb;
1224 if ( fullsize+cache_fill >= CACHE_SIZE ) {
1225 size_t overlap = CACHE_SIZE-cache_fill;
1226 memcpy(cache_buffer+cache_fill, (unsigned char*)ptr, overlap);
1227 if ( fwrite(cache_buffer, 1, CACHE_SIZE, fd) != CACHE_SIZE ) return 0;
1228 fullsize -= overlap;
1229 if ( fullsize >= CACHE_SIZE ) {
1230 cache_fill = fullsize % CACHE_SIZE;
1231 if ( cache_fill ) memcpy(cache_buffer, (unsigned char*)ptr+overlap+fullsize-cache_fill, cache_fill);
1232 if ( fwrite((unsigned char*)ptr+overlap, 1, fullsize-cache_fill, fd) != fullsize-cache_fill ) return 0;
1233 }
1234 else {
1235 memcpy(cache_buffer, (unsigned char*)ptr+overlap, fullsize);
1236 cache_fill = fullsize;
1237 }
1238 }
1239 else {
1240 memcpy(cache_buffer+cache_fill, (unsigned char*)ptr, fullsize);
1241 cache_fill += fullsize;
1242 }
1243 return nmemb;
1244}
1245
1246size_t flush_cache(FILE *fd)
1247{
1248 if ( cache_fill ) {
1249 size_t retval = fwrite(cache_buffer, 1, cache_fill, fd);
1250 if ( retval != cache_fill ) {
1251 cache_fill = 0;
1252 return 0;
1253 }
1254 cache_fill = 0;
1255 }
1256 return 1;
1257}
1258#else
1259size_t fwrite_cached(const void *ptr, size_t size, size_t nmemb, FILE *fd)
1260{
1261 return fwrite(ptr, size, nmemb, fd);
1262}
1263
1264size_t flush_cache(FILE *fd)
1265{
1266 DUMMYUSE(fd)
1267 return 1;
1268}
1269#endif
1270
1271/*
1272 #] Cached file operation functions :
1273 #[ Helper Macros :
1274*/
1275
1276/* some helper macros to streamline the code in DoSnapshot() and DoRecovery() */
1277
1278/* freeing memory */
1279
1280#define R_FREE(ARG) \
1281 if ( ARG ) M_free(ARG, #ARG);
1282
1283#define R_FREE_NAMETREE(ARG) \
1284 R_FREE(ARG->namenode); \
1285 R_FREE(ARG->namebuffer); \
1286 R_FREE(ARG);
1287
1288#define R_FREE_STREAM(ARG) \
1289 R_FREE(ARG.buffer); \
1290 R_FREE(ARG.FoldName); \
1291 R_FREE(ARG.name);
1292
1293/* reading a single variable */
1294
1295#define R_SET(VAR,TYPE) \
1296 VAR = *((TYPE*)p); p = (unsigned char*)p + sizeof(TYPE);
1297
1298/* general buffer */
1299
1300#define R_COPY_B(VAR,SIZE,CAST) \
1301 VAR = (CAST)Malloc1(SIZE,#VAR); \
1302 memcpy(VAR, p, SIZE); p = (unsigned char*)p + SIZE;
1303
1304#define S_WRITE_B(BUF,LEN) \
1305 if ( fwrite_cached(BUF, 1, LEN, fd) != (size_t)(LEN) ) return(__LINE__);
1306
1307#define S_FLUSH_B \
1308 if ( flush_cache(fd) != 1 ) return(__LINE__);
1309
1310/* character strings */
1311
1312#define R_COPY_S(VAR,CAST) \
1313 if ( VAR ) { \
1314 VAR = (CAST)Malloc1(strlen(p)+1,"R_COPY_S"); \
1315 strcpy((char*)VAR, p); p = (unsigned char*)p + strlen(p) + 1; \
1316 }
1317
1318#define S_WRITE_S(STR) \
1319 if ( STR ) { \
1320 l = strlen((char*)STR) + 1; \
1321 if ( fwrite_cached(STR, 1, l, fd) != (size_t)l ) return(__LINE__); \
1322 }
1323
1324/* LIST */
1325
1326#define R_COPY_LIST(ARG) \
1327 if ( ARG.maxnum ) { \
1328 R_COPY_B(ARG.lijst, ARG.size*ARG.maxnum, void*) \
1329 }
1330
1331#define S_WRITE_LIST(LST) \
1332 if ( LST.maxnum ) { \
1333 S_WRITE_B((char*)LST.lijst, LST.maxnum*LST.size) \
1334 }
1335
1336/* NAMETREE */
1337
1338#define R_COPY_NAMETREE(ARG) \
1339 R_COPY_B(ARG, sizeof(NAMETREE), NAMETREE*); \
1340 if ( ARG->namenode ) { \
1341 R_COPY_B(ARG->namenode, ARG->nodesize*sizeof(NAMENODE), NAMENODE*); \
1342 } \
1343 if ( ARG->namebuffer ) { \
1344 R_COPY_B(ARG->namebuffer, ARG->namesize, UBYTE*); \
1345 }
1346
1347#define S_WRITE_NAMETREE(ARG) \
1348 S_WRITE_B(ARG, sizeof(NAMETREE)); \
1349 if ( ARG->namenode ) { \
1350 S_WRITE_B(ARG->namenode, ARG->nodesize*sizeof(struct NaMeNode)); \
1351 } \
1352 if ( ARG->namebuffer ) { \
1353 S_WRITE_B(ARG->namebuffer, ARG->namesize); \
1354 }
1355
1356/* DOLLAR */
1357
1358#define S_WRITE_DOLLAR(ARG) \
1359 if ( ARG.size && ARG.where && ARG.where != &(AM.dollarzero) ) { \
1360 S_WRITE_B(ARG.where, ARG.size*sizeof(WORD)) \
1361 }
1362
1363/* Printing time marks with ANNOUNCE macro */
1364
1365#ifdef PRINTTIMEMARKS
1366time_t announce_time;
1367#define ANNOUNCE(str) time(&announce_time); MesPrint("TIMEMARK %s %s", ctime(&announce_time), #str);
1368#else
1369#define ANNOUNCE(str)
1370#endif
1371
1372/*
1373 #] Helper Macros :
1374 #[ DoRecovery :
1375*/
1376
1401int DoRecovery(int *moduletype)
1402{
1403 GETIDENTITY
1404 FILE *fd;
1405 POSITION pos;
1406 void *buf, *p;
1407 LONG size, l;
1408 int i, j;
1409 UBYTE *org;
1410 char *namebufout, *namebufhide;
1411 LONG ofs;
1412 void *oldAMdollarzero;
1413 LIST PotModDolListBackup;
1414 LIST ModOptDolListBackup;
1415 WORD oldLogHandle;
1416
1417 MesPrint("Recovering ... %"); fflush(0);
1418
1419 if ( !(fd = fopen(recoveryfile, "r")) ) return(__LINE__);
1420
1421 /* load the complete recovery file into a buffer */
1422 if ( fread(&pos, sizeof(POSITION), 1, fd) != 1 ) return(__LINE__);
1423 size = BASEPOSITION(pos) - sizeof(POSITION);
1424 buf = Malloc1(size, "recovery buffer");
1425 if ( fread(buf, size, 1, fd) != 1 ) return(__LINE__);
1426
1427 /* pointer p will go through the buffer in the following */
1428 p = buf;
1429
1430 /* read moduletype */
1431 R_SET(*moduletype, int);
1432
1433 /*#[ AM : */
1434
1435 /* only certain elements will be restored. the rest of AM should have gotten
1436 * the correct values at startup. */
1437
1438 R_SET(AM.hparallelflag, int);
1439 R_SET(AM.gparallelflag, int);
1440 R_SET(AM.gCodesFlag, int);
1441 R_SET(AM.gNamesFlag, int);
1442 R_SET(AM.gStatsFlag, int);
1443 R_SET(AM.gTokensWriteFlag, int);
1444 R_SET(AM.gNoSpacesInNumbers, int);
1445 R_SET(AM.gIndentSpace, WORD);
1446 R_SET(AM.gUnitTrace, WORD);
1447 R_SET(AM.gDefDim, int);
1448 R_SET(AM.gDefDim4, int);
1449 R_SET(AM.gncmod, WORD);
1450 R_SET(AM.gnpowmod, WORD);
1451 R_SET(AM.gmodmode, WORD);
1452 R_SET(AM.gOutputMode, WORD);
1453 R_SET(AM.gCnumpows, WORD);
1454 R_SET(AM.gOutputSpaces, WORD);
1455 R_SET(AM.gOutNumberType, WORD);
1456 R_SET(AM.gfunpowers, int);
1457 R_SET(AM.gPolyFun, WORD);
1458 R_SET(AM.gPolyFunInv, WORD);
1459 R_SET(AM.gPolyFunType, WORD);
1460 R_SET(AM.gPolyFunExp, WORD);
1461 R_SET(AM.gPolyFunVar, WORD);
1462 R_SET(AM.gPolyFunPow, WORD);
1463 R_SET(AM.gProcessBucketSize, LONG);
1464 R_SET(AM.OldChildTime, LONG);
1465 R_SET(AM.OldSecTime, LONG);
1466 R_SET(AM.OldMilliTime, LONG);
1467 R_SET(AM.gproperorderflag, int);
1468 R_SET(AM.gThreadBucketSize, LONG);
1469 R_SET(AM.gSizeCommuteInSet, int);
1470 R_SET(AM.gThreadStats, int);
1471 R_SET(AM.gFinalStats, int);
1472 R_SET(AM.gThreadsFlag, int);
1473 R_SET(AM.gThreadBalancing, int);
1474 R_SET(AM.gThreadSortFileSynch, int);
1475 R_SET(AM.gProcessStats, int);
1476 R_SET(AM.gOldParallelStats, int);
1477 R_SET(AM.gSortType, int);
1478 R_SET(AM.gShortStatsMax, WORD);
1479 R_SET(AM.gIsFortran90, int);
1480 R_SET(oldAMdollarzero, void*);
1481 R_FREE(AM.gFortran90Kind);
1482 R_SET(AM.gFortran90Kind,UBYTE *);
1483 R_COPY_S(AM.gFortran90Kind,UBYTE *);
1484
1485 R_COPY_S(AM.gextrasym,UBYTE *);
1486 R_COPY_S(AM.ggextrasym,UBYTE *);
1487
1488 R_SET(AM.PrintTotalSize,int);
1489 R_SET(AM.fbuffersize,int);
1490 R_SET(AM.gOldFactArgFlag,int);
1491 R_SET(AM.ggOldFactArgFlag,int);
1492
1493 R_SET(AM.gnumextrasym,int);
1494 R_SET(AM.ggnumextrasym,int);
1495 R_SET(AM.NumSpectatorFiles,int);
1496 R_SET(AM.SizeForSpectatorFiles,int);
1497 R_SET(AM.gOldGCDflag,int);
1498 R_SET(AM.ggOldGCDflag,int);
1499 R_SET(AM.gWTimeStatsFlag, int);
1500
1501 R_FREE(AM.Path);
1502 R_SET(AM.Path,UBYTE *);
1503 R_COPY_S(AM.Path,UBYTE *);
1504
1505 R_SET(AM.FromStdin, BOOL);
1506
1507#ifdef PRINTDEBUG
1508 print_M();
1509#endif
1510
1511 /*#] AM : */
1512 /*#[ AC : */
1513
1514 /* #[ AC free pointers */
1515
1516 /* AC will be overwritten by data from the recovery file, therefore
1517 * dynamically allocated memory must be freed first. */
1518
1519 R_FREE_NAMETREE(AC.dollarnames);
1520 R_FREE_NAMETREE(AC.exprnames);
1521 R_FREE_NAMETREE(AC.varnames);
1522 for ( i=0; i<AC.ChannelList.num; ++i ) {
1523 R_FREE(channels[i].name);
1524 }
1525 R_FREE(AC.ChannelList.lijst);
1526 R_FREE(AC.DubiousList.lijst);
1527 for ( i=0; i<AC.FunctionList.num; ++i ) {
1528 TABLES T = functions[i].tabl;
1529 if ( T ) {
1530 R_FREE(T->buffers);
1531 R_FREE(T->mm);
1532 R_FREE(T->flags);
1533 R_FREE(T->prototype);
1534 R_FREE(T->tablepointers);
1535 if ( T->sparse ) {
1536 R_FREE(T->boomlijst);
1537 R_FREE(T->argtail);
1538 }
1539 if ( T->spare ) {
1540 R_FREE(T->spare->buffers);
1541 R_FREE(T->spare->mm);
1542 R_FREE(T->spare->flags);
1543 R_FREE(T->spare->tablepointers);
1544 if ( T->spare->sparse ) {
1545 R_FREE(T->spare->boomlijst);
1546 }
1547 R_FREE(T->spare);
1548 }
1549 R_FREE(T);
1550 }
1551 }
1552 R_FREE(AC.FunctionList.lijst);
1553 for ( i=0; i<AC.ExpressionList.num; ++i ) {
1554 if ( Expressions[i].renum ) {
1555 R_FREE(Expressions[i].renum->symb.lo);
1556 R_FREE(Expressions[i].renum);
1557 }
1558 if ( Expressions[i].bracketinfo ) {
1559 R_FREE(Expressions[i].bracketinfo->indexbuffer);
1560 R_FREE(Expressions[i].bracketinfo->bracketbuffer);
1561 R_FREE(Expressions[i].bracketinfo);
1562 }
1563 if ( Expressions[i].newbracketinfo ) {
1564 R_FREE(Expressions[i].newbracketinfo->indexbuffer);
1565 R_FREE(Expressions[i].newbracketinfo->bracketbuffer);
1566 R_FREE(Expressions[i].newbracketinfo);
1567 }
1568 if ( Expressions[i].renumlists != AN.dummyrenumlist ) {
1569 R_FREE(Expressions[i].renumlists);
1570 }
1571 R_FREE(Expressions[i].inmem);
1572 }
1573 R_FREE(AC.ExpressionList.lijst);
1574 R_FREE(AC.IndexList.lijst);
1575 R_FREE(AC.SetElementList.lijst);
1576 R_FREE(AC.SetList.lijst);
1577 R_FREE(AC.SymbolList.lijst);
1578 R_FREE(AC.VectorList.lijst);
1579 for ( i=0; i<AC.TableBaseList.num; ++i ) {
1580 R_FREE(tablebases[i].iblocks);
1581 R_FREE(tablebases[i].nblocks);
1582 R_FREE(tablebases[i].name);
1583 R_FREE(tablebases[i].fullname);
1584 R_FREE(tablebases[i].tablenames);
1585 }
1586 R_FREE(AC.TableBaseList.lijst);
1587 for ( i=0; i<AC.cbufList.num; ++i ) {
1588 R_FREE(cbuf[i].Buffer);
1589 R_FREE(cbuf[i].lhs);
1590 R_FREE(cbuf[i].rhs);
1591 R_FREE(cbuf[i].boomlijst);
1592 }
1593 R_FREE(AC.cbufList.lijst);
1594 R_FREE(AC.AutoSymbolList.lijst);
1595 R_FREE(AC.AutoIndexList.lijst);
1596 R_FREE(AC.AutoVectorList.lijst);
1597 /* Tables cannot be auto-declared, therefore no extra code here */
1598 R_FREE(AC.AutoFunctionList.lijst);
1599 R_FREE_NAMETREE(AC.autonames);
1600 for ( i=0; i<AC.NumStreams; ++i ) {
1601 R_FREE_STREAM(AC.Streams[i]);
1602 }
1603 R_FREE(AC.Streams);
1604 R_FREE(AC.termstack);
1605 R_FREE(AC.termsortstack);
1606 R_FREE(AC.cmod);
1607 R_FREE(AC.modpowers);
1608 R_FREE(AC.halfmod);
1609 R_FREE(AC.IfHeap);
1610 R_FREE(AC.IfCount);
1611 R_FREE(AC.iBuffer);
1612 for ( i=0; i<AC.NumLabels; ++i ) {
1613 R_FREE(AC.LabelNames[i]);
1614 }
1615 R_FREE(AC.LabelNames);
1616 R_FREE(AC.FixIndices);
1617 R_FREE(AC.termsumcheck);
1618 R_FREE(AC.WildcardNames);
1619 R_FREE(AC.tokens);
1620 R_FREE(AC.tokenarglevel);
1621 R_FREE(AC.modinverses);
1622 R_FREE(AC.Fortran90Kind);
1623#ifdef WITHPTHREADS
1624 R_FREE(AC.inputnumbers);
1625#endif
1626 R_FREE(AC.IfSumCheck);
1627 R_FREE(AC.CommuteInSet);
1628 R_FREE(AC.CheckpointRunAfter);
1629 R_FREE(AC.CheckpointRunBefore);
1630
1631 /* #] AC free pointers */
1632
1633 /* backup some lists in order to restore it to the initial setup */
1634 PotModDolListBackup = AC.PotModDolList;
1635 ModOptDolListBackup = AC.ModOptDolList;
1636 oldLogHandle = AC.LogHandle;
1637
1638 /* first we copy AC as a whole and then restore the pointer structures step
1639 by step. */
1640
1641 AC = *((struct C_const*)p); p = (unsigned char*)p + sizeof(struct C_const);
1642
1643 R_COPY_NAMETREE(AC.dollarnames);
1644 R_COPY_NAMETREE(AC.exprnames);
1645 R_COPY_NAMETREE(AC.varnames);
1646
1647 R_COPY_LIST(AC.ChannelList);
1648 for ( i=0; i<AC.ChannelList.num; ++i ) {
1649 R_COPY_S(channels[i].name,char*);
1650 channels[i].handle = ReOpenFile(channels[i].name);
1651 }
1652 AC.ChannelList.message = "channel buffer";
1653
1654 AC.DubiousList.lijst = 0;
1655 AC.DubiousList.message = "ambiguous variable";
1656 AC.DubiousList.num =
1657 AC.DubiousList.maxnum =
1658 AC.DubiousList.numglobal =
1659 AC.DubiousList.numtemp =
1660 AC.DubiousList.numclear = 0;
1661
1662 R_COPY_LIST(AC.FunctionList);
1663 for ( i=0; i<AC.FunctionList.num; ++i ) {
1664 if ( functions[i].tabl ) {
1665 TABLES tabl;
1666 R_COPY_B(tabl, sizeof(struct TaBlEs), TABLES);
1667 functions[i].tabl = tabl;
1668 if ( tabl->tablepointers ) {
1669 if ( tabl->sparse ) {
1670 R_COPY_B(tabl->tablepointers,
1671 tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION),
1672 WORD*);
1673 }
1674 else {
1675 R_COPY_B(tabl->tablepointers,
1676 TABLEEXTENSION*sizeof(WORD)*(tabl->totind), WORD*);
1677 }
1678 }
1679 org = (UBYTE*)tabl->prototype;
1680#ifdef WITHPTHREADS
1681 R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD**);
1682 ofs = (UBYTE*)tabl->prototype - org;
1683 for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1684 if ( tabl->prototype[j] ) {
1685 tabl->prototype[j] = (WORD*)((UBYTE*)tabl->prototype[j] + ofs);
1686 }
1687 }
1688 if ( tabl->pattern ) {
1689 tabl->pattern = (WORD**)((UBYTE*)tabl->pattern + ofs);
1690 for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1691 if ( tabl->pattern[j] ) {
1692 tabl->pattern[j] = (WORD*)((UBYTE*)tabl->pattern[j] + ofs);
1693 }
1694 }
1695 }
1696#else
1697 ofs = tabl->pattern - tabl->prototype;
1698 R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD*);
1699 if ( tabl->pattern ) {
1700 tabl->pattern = tabl->prototype + ofs;
1701 }
1702#endif
1703 R_COPY_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX), MINMAX*);
1704 R_COPY_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD), WORD*);
1705 if ( tabl->sparse ) {
1706 R_COPY_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
1707 R_COPY_S(tabl->argtail,UBYTE*);
1708 }
1709 R_COPY_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD), WORD*);
1710 if ( tabl->spare ) {
1711 TABLES spare;
1712 R_COPY_B(spare, sizeof(struct TaBlEs), TABLES);
1713 tabl->spare = spare;
1714 if ( spare->tablepointers ) {
1715 if ( spare->sparse ) {
1716 R_COPY_B(spare->tablepointers,
1717 spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION),
1718 WORD*);
1719 }
1720 else {
1721 R_COPY_B(spare->tablepointers,
1722 TABLEEXTENSION*sizeof(WORD)*(spare->totind), WORD*);
1723 }
1724 }
1725 spare->prototype = tabl->prototype;
1726 spare->pattern = tabl->pattern;
1727 R_COPY_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX), MINMAX*);
1728 R_COPY_B(spare->flags, spare->numind*(LONG)sizeof(WORD), WORD*);
1729 if ( tabl->sparse ) {
1730 R_COPY_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
1731 spare->argtail = tabl->argtail;
1732 }
1733 spare->spare = tabl;
1734 R_COPY_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD), WORD*);
1735 }
1736 }
1737 }
1738 AC.FunctionList.message = "function";
1739
1740 R_COPY_LIST(AC.ExpressionList);
1741 for ( i=0; i<AC.ExpressionList.num; ++i ) {
1742 EXPRESSIONS ex = Expressions + i;
1743 if ( ex->renum ) {
1744 R_COPY_B(ex->renum, sizeof(struct ReNuMbEr), RENUMBER);
1745 org = (UBYTE*)ex->renum->symb.lo;
1746 R_SET(size, size_t);
1747 R_COPY_B(ex->renum->symb.lo, size, WORD*);
1748 ofs = (UBYTE*)ex->renum->symb.lo - org;
1749 ex->renum->symb.start = (WORD*)((UBYTE*)ex->renum->symb.start + ofs);
1750 ex->renum->symb.hi = (WORD*)((UBYTE*)ex->renum->symb.hi + ofs);
1751 ex->renum->indi.lo = (WORD*)((UBYTE*)ex->renum->indi.lo + ofs);
1752 ex->renum->indi.start = (WORD*)((UBYTE*)ex->renum->indi.start + ofs);
1753 ex->renum->indi.hi = (WORD*)((UBYTE*)ex->renum->indi.hi + ofs);
1754 ex->renum->vect.lo = (WORD*)((UBYTE*)ex->renum->vect.lo + ofs);
1755 ex->renum->vect.start = (WORD*)((UBYTE*)ex->renum->vect.start + ofs);
1756 ex->renum->vect.hi = (WORD*)((UBYTE*)ex->renum->vect.hi + ofs);
1757 ex->renum->func.lo = (WORD*)((UBYTE*)ex->renum->func.lo + ofs);
1758 ex->renum->func.start = (WORD*)((UBYTE*)ex->renum->func.start + ofs);
1759 ex->renum->func.hi = (WORD*)((UBYTE*)ex->renum->func.hi + ofs);
1760 ex->renum->symnum = (WORD*)((UBYTE*)ex->renum->symnum + ofs);
1761 ex->renum->indnum = (WORD*)((UBYTE*)ex->renum->indnum + ofs);
1762 ex->renum->vecnum = (WORD*)((UBYTE*)ex->renum->vecnum + ofs);
1763 ex->renum->funnum = (WORD*)((UBYTE*)ex->renum->funnum + ofs);
1764 }
1765 if ( ex->bracketinfo ) {
1766 R_COPY_B(ex->bracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
1767 R_COPY_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
1768 R_COPY_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
1769 }
1770 if ( ex->newbracketinfo ) {
1771 R_COPY_B(ex->newbracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
1772 R_COPY_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
1773 R_COPY_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
1774 }
1775#ifdef WITHPTHREADS
1776 ex->renumlists = 0;
1777#else
1778 ex->renumlists = AN.dummyrenumlist;
1779#endif
1780 if ( ex->inmem ) {
1781 R_SET(size, size_t);
1782 R_COPY_B(ex->inmem, size, WORD*);
1783 }
1784 }
1785 AC.ExpressionList.message = "expression";
1786
1787 R_COPY_LIST(AC.IndexList);
1788 AC.IndexList.message = "index";
1789 R_COPY_LIST(AC.SetElementList);
1790 AC.SetElementList.message = "set element";
1791 R_COPY_LIST(AC.SetList);
1792 AC.SetList.message = "set";
1793 R_COPY_LIST(AC.SymbolList);
1794 AC.SymbolList.message = "symbol";
1795 R_COPY_LIST(AC.VectorList);
1796 AC.VectorList.message = "vector";
1797
1798 AC.PotModDolList = PotModDolListBackup;
1799 AC.ModOptDolList = ModOptDolListBackup;
1800
1801 R_COPY_LIST(AC.TableBaseList);
1802 for ( i=0; i<AC.TableBaseList.num; ++i ) {
1803 if ( tablebases[i].iblocks ) {
1804 R_COPY_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks*sizeof(INDEXBLOCK*),INDEXBLOCK**);
1805 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
1806 if ( tablebases[i].iblocks[j] ) {
1807 R_COPY_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK), INDEXBLOCK*);
1808 }
1809 }
1810 }
1811 if ( tablebases[i].nblocks ) {
1812 R_COPY_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks*sizeof(NAMESBLOCK*),NAMESBLOCK**);
1813 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
1814 if ( tablebases[i].nblocks[j] ) {
1815 R_COPY_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK), NAMESBLOCK*);
1816 }
1817 }
1818 }
1819 /* reopen file */
1820 if ( ( tablebases[i].handle = fopen(tablebases[i].fullname, "r+b") ) == NULL ) {
1821 MesPrint("ERROR: Could not reopen tablebase %s!",tablebases[i].name);
1822 Terminate(-1);
1823 }
1824 R_COPY_S(tablebases[i].name,char*);
1825 R_COPY_S(tablebases[i].fullname,char*);
1826 R_COPY_S(tablebases[i].tablenames,char*);
1827 }
1828 AC.TableBaseList.message = "list of tablebases";
1829
1830 R_COPY_LIST(AC.cbufList);
1831 for ( i=0; i<AC.cbufList.num; ++i ) {
1832 org = (UBYTE*)cbuf[i].Buffer;
1833 R_COPY_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD), WORD*);
1834 ofs = (UBYTE*)cbuf[i].Buffer - org;
1835 cbuf[i].Top = (WORD*)((UBYTE*)cbuf[i].Top + ofs);
1836 cbuf[i].Pointer = (WORD*)((UBYTE*)cbuf[i].Pointer + ofs);
1837 R_COPY_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*), WORD**);
1838 for ( j=1; j<=cbuf[i].numlhs; ++j ) {
1839 if ( cbuf[i].lhs[j] ) cbuf[i].lhs[j] = (WORD*)((UBYTE*)cbuf[i].lhs[j] + ofs);
1840 }
1841 org = (UBYTE*)cbuf[i].rhs;
1842 R_COPY_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)), WORD**);
1843 for ( j=1; j<=cbuf[i].numrhs; ++j ) {
1844 if ( cbuf[i].rhs[j] ) cbuf[i].rhs[j] = (WORD*)((UBYTE*)cbuf[i].rhs[j] + ofs);
1845 }
1846 ofs = (UBYTE*)cbuf[i].rhs - org;
1847 cbuf[i].CanCommu = (LONG*)((UBYTE*)cbuf[i].CanCommu + ofs);
1848 cbuf[i].NumTerms = (LONG*)((UBYTE*)cbuf[i].NumTerms + ofs);
1849 cbuf[i].numdum = (WORD*)((UBYTE*)cbuf[i].numdum + ofs);
1850 cbuf[i].dimension = (WORD*)((UBYTE*)cbuf[i].dimension + ofs);
1851 if ( cbuf[i].boomlijst ) {
1852 R_COPY_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*sizeof(COMPTREE), COMPTREE*);
1853 }
1854 }
1855 AC.cbufList.message = "compiler buffer";
1856
1857 R_COPY_LIST(AC.AutoSymbolList);
1858 AC.AutoSymbolList.message = "autosymbol";
1859 R_COPY_LIST(AC.AutoIndexList);
1860 AC.AutoIndexList.message = "autoindex";
1861 R_COPY_LIST(AC.AutoVectorList);
1862 AC.AutoVectorList.message = "autovector";
1863 R_COPY_LIST(AC.AutoFunctionList);
1864 AC.AutoFunctionList.message = "autofunction";
1865
1866 R_COPY_NAMETREE(AC.autonames);
1867
1868 AC.Symbols = &(AC.SymbolList);
1869 AC.Indices = &(AC.IndexList);
1870 AC.Vectors = &(AC.VectorList);
1871 AC.Functions = &(AC.FunctionList);
1872 AC.activenames = &(AC.varnames);
1873
1874 org = (UBYTE*)AC.Streams;
1875 R_COPY_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM), STREAM*);
1876 for ( i=0; i<AC.NumStreams; ++i ) {
1877 if ( AC.Streams[i].type != FILESTREAM ) {
1878 UBYTE *org2;
1879 org2 = AC.Streams[i].buffer;
1880 if ( AC.Streams[i].inbuffer ) {
1881 R_COPY_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer, UBYTE*);
1882 }
1883 ofs = AC.Streams[i].buffer - org2;
1884 AC.Streams[i].pointer += ofs;
1885 AC.Streams[i].top += ofs;
1886 }
1887 else {
1888 p = (unsigned char*)p + AC.Streams[i].inbuffer;
1889 }
1890 AC.Streams[i].buffersize = AC.Streams[i].inbuffer;
1891 R_COPY_S(AC.Streams[i].FoldName,UBYTE*);
1892 R_COPY_S(AC.Streams[i].name,UBYTE*);
1893 if ( AC.Streams[i].type == PREVARSTREAM || AC.Streams[i].type == DOLLARSTREAM ) {
1894 AC.Streams[i].pname = AC.Streams[i].name;
1895 }
1896 else if ( AC.Streams[i].type == FILESTREAM ) {
1897 UBYTE *org2;
1898 org2 = AC.Streams[i].buffer;
1899 AC.Streams[i].buffer = (UBYTE*)Malloc1(AC.Streams[i].buffersize, "buffer");
1900 ofs = AC.Streams[i].buffer - org2;
1901 AC.Streams[i].pointer += ofs;
1902 AC.Streams[i].top += ofs;
1903
1904 /* open file except for already opened main input file */
1905 if ( i ) {
1906 AC.Streams[i].handle = OpenFile((char *)(AC.Streams[i].name));
1907 if ( AC.Streams[i].handle == -1 ) {
1908 MesPrint("ERROR: Could not reopen stream %s!",AC.Streams[i].name);
1909 Terminate(-1);
1910 }
1911 }
1912
1913 PUTZERO(pos);
1914 ADDPOS(pos, AC.Streams[i].bufferposition);
1915 SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
1916
1917 AC.Streams[i].inbuffer = ReadFile(AC.Streams[i].handle, AC.Streams[i].buffer, AC.Streams[i].inbuffer);
1918
1919 SETBASEPOSITION(pos, AC.Streams[i].fileposition);
1920 SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
1921 }
1922 /*
1923 * Ideally, we should check if we have a type PREREADSTREAM, PREREADSTREAM2, and
1924 * PRECALCSTREAM here. If so, we should free element name and point it
1925 * to the name element of the embracing stream's struct. In practice,
1926 * this is undoable without adding new data to STREAM. Since we create
1927 * only a small memory leak here (some few byte for each existing
1928 * stream of these types) and only once when we do a recovery, we
1929 * tolerate this leak and keep it STREAM as it is.
1930 */
1931 }
1932 ofs = (UBYTE*)AC.Streams - org;
1933 AC.CurrentStream = (STREAM*)((UBYTE*)AC.CurrentStream + ofs);
1934
1935 if ( AC.termstack ) {
1936 R_COPY_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
1937 }
1938
1939 if ( AC.termsortstack ) {
1940 R_COPY_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
1941 }
1942
1943 /* exception: here we also change values from struct AM */
1944 R_COPY_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD), UWORD*);
1945 AM.gcmod = AC.cmod + AM.MaxTal;
1946 AC.powmod = AM.gcmod + AM.MaxTal;
1947 AM.gpowmod = AC.powmod + AM.MaxTal;
1948
1949 AC.modpowers = 0;
1950 AC.halfmod = 0;
1951
1952 /* we don't care about AC.ProtoType/WildC */
1953
1954 if ( AC.IfHeap ) {
1955 ofs = AC.IfStack - AC.IfHeap;
1956 R_COPY_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
1957 AC.IfStack = AC.IfHeap + ofs;
1958 R_COPY_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
1959 }
1960
1961 org = AC.iBuffer;
1962 size = AC.iStop - AC.iBuffer + 2;
1963 R_COPY_B(AC.iBuffer, size, UBYTE*);
1964 ofs = AC.iBuffer - org;
1965 AC.iPointer += ofs;
1966 AC.iStop += ofs;
1967
1968 if ( AC.LabelNames ) {
1969 org = (UBYTE*)AC.LabelNames;
1970 R_COPY_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)), UBYTE**);
1971 for ( i=0; i<AC.NumLabels; ++i ) {
1972 R_COPY_S(AC.LabelNames[i],UBYTE*);
1973 }
1974 ofs = (UBYTE*)AC.LabelNames - org;
1975 AC.Labels = (int*)((UBYTE*)AC.Labels + ofs);
1976 }
1977
1978 R_COPY_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD), WORD*);
1979
1980 if ( AC.termsumcheck ) {
1981 R_COPY_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD), WORD*);
1982 }
1983
1984 R_COPY_B(AC.WildcardNames, AC.WildcardBufferSize, UBYTE*);
1985
1986 if ( AC.tokens ) {
1987 size = AC.toptokens - AC.tokens;
1988 if ( size ) {
1989 org = (UBYTE*)AC.tokens;
1990 R_COPY_B(AC.tokens, size, SBYTE*);
1991 ofs = (UBYTE*)AC.tokens - org;
1992 AC.endoftokens += ofs;
1993 AC.toptokens += ofs;
1994 }
1995 else {
1996 AC.tokens = 0;
1997 AC.endoftokens = AC.tokens;
1998 AC.toptokens = AC.tokens;
1999 }
2000 }
2001
2002 R_COPY_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD), WORD*);
2003
2004 AC.modinverses = 0;
2005
2006 R_COPY_S(AC.Fortran90Kind,UBYTE *);
2007
2008#ifdef WITHPTHREADS
2009 if ( AC.inputnumbers ) {
2010 org = (UBYTE*)AC.inputnumbers;
2011 R_COPY_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)), LONG*);
2012 ofs = (UBYTE*)AC.inputnumbers - org;
2013 AC.pfirstnum = (WORD*)((UBYTE*)AC.pfirstnum + ofs);
2014 }
2015 AC.halfmodlock = dummylock;
2016#endif /* ifdef WITHPTHREADS */
2017
2018 if ( AC.IfSumCheck ) {
2019 R_COPY_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1), WORD*);
2020 }
2021 if ( AC.CommuteInSet ) {
2022 R_COPY_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1), WORD*);
2023 }
2024
2025 AC.LogHandle = oldLogHandle;
2026
2027 R_COPY_S(AC.CheckpointRunAfter,char*);
2028 R_COPY_S(AC.CheckpointRunBefore,char*);
2029
2030 R_COPY_S(AC.extrasym,UBYTE *);
2031
2032#ifdef PRINTDEBUG
2033 print_C();
2034#endif
2035
2036 /*#] AC : */
2037 /*#[ AP : */
2038
2039 /* #[ AP free pointers */
2040
2041 /* AP will be overwritten by data from the recovery file, therefore
2042 * dynamically allocated memory must be freed first. */
2043
2044 for ( i=0; i<AP.DollarList.num; ++i ) {
2045 if ( Dollars[i].size ) {
2046 R_FREE(Dollars[i].where);
2047 }
2048 CleanDollarFactors(Dollars+i);
2049 }
2050 R_FREE(AP.DollarList.lijst);
2051
2052 for ( i=0; i<AP.PreVarList.num; ++i ) {
2053 R_FREE(PreVar[i].name);
2054 }
2055 R_FREE(AP.PreVarList.lijst);
2056
2057 for ( i=0; i<AP.LoopList.num; ++i ) {
2058 R_FREE(DoLoops[i].p.buffer);
2059 if ( DoLoops[i].dollarname ) {
2060 R_FREE(DoLoops[i].dollarname);
2061 }
2062 }
2063 R_FREE(AP.LoopList.lijst);
2064
2065 for ( i=0; i<AP.ProcList.num; ++i ) {
2066 R_FREE(Procedures[i].p.buffer);
2067 R_FREE(Procedures[i].name);
2068 }
2069 R_FREE(AP.ProcList.lijst);
2070
2071 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2072 R_FREE(AP.PreSwitchStrings[i]);
2073 }
2074 R_FREE(AP.PreSwitchStrings);
2075 R_FREE(AP.preStart);
2076 R_FREE(AP.procedureExtension);
2077 R_FREE(AP.cprocedureExtension);
2078 R_FREE(AP.PreIfStack);
2079 R_FREE(AP.PreSwitchModes);
2080 R_FREE(AP.PreTypes);
2081
2082 /* #] AP free pointers */
2083
2084 /* first we copy AP as a whole and then restore the pointer structures step
2085 by step. */
2086
2087 AP = *((struct P_const*)p); p = (unsigned char*)p + sizeof(struct P_const);
2088#ifdef WITHPTHREADS
2089 AP.PreVarLock = dummylock;
2090#endif
2091
2092 R_COPY_LIST(AP.DollarList);
2093 for ( i=0; i<AP.DollarList.num; ++i ) {
2094 DOLLARS d = Dollars + i;
2095 size = d->size * sizeof(WORD);
2096 if ( size && d->where && d->where != oldAMdollarzero ) {
2097 R_COPY_B(d->where, size, void*);
2098 }
2099#ifdef WITHPTHREADS
2100 d->pthreadslockread = dummylock;
2101 d->pthreadslockwrite = dummylock;
2102#endif
2103 if ( d->nfactors > 1 ) {
2104 R_COPY_B(d->factors,sizeof(FACDOLLAR)*d->nfactors,FACDOLLAR*);
2105 for ( j = 0; j < d->nfactors; j++ ) {
2106 if ( d->factors[j].size > 0 ) {
2107 R_COPY_B(d->factors[i].where,sizeof(WORD)*(d->factors[j].size+1),WORD*);
2108 }
2109 }
2110 }
2111 }
2112 AP.DollarList.message = "$-variable";
2113
2114 R_COPY_LIST(AP.PreVarList);
2115 for ( i=0; i<AP.PreVarList.num; ++i ) {
2116 R_SET(size, size_t);
2117 org = PreVar[i].name;
2118 R_COPY_B(PreVar[i].name, size, UBYTE*);
2119 ofs = PreVar[i].name - org;
2120 if ( PreVar[i].value ) PreVar[i].value += ofs;
2121 if ( PreVar[i].argnames ) PreVar[i].argnames += ofs;
2122 }
2123 AP.PreVarList.message = "PreVariable";
2124
2125 R_COPY_LIST(AP.LoopList);
2126 for ( i=0; i<AP.LoopList.num; ++i ) {
2127 org = DoLoops[i].p.buffer;
2128 R_COPY_B(DoLoops[i].p.buffer, DoLoops[i].p.size, UBYTE*);
2129 ofs = DoLoops[i].p.buffer - org;
2130 if ( DoLoops[i].name ) DoLoops[i].name += ofs;
2131 if ( DoLoops[i].vars ) DoLoops[i].vars += ofs;
2132 if ( DoLoops[i].contents ) DoLoops[i].contents += ofs;
2133 if ( DoLoops[i].type == ONEEXPRESSION ) {
2134 R_COPY_S(DoLoops[i].dollarname,UBYTE*);
2135 }
2136 }
2137 AP.LoopList.message = "doloop";
2138
2139 R_COPY_LIST(AP.ProcList);
2140 for ( i=0; i<AP.ProcList.num; ++i ) {
2141 if ( Procedures[i].p.size ) {
2142 if ( Procedures[i].loadmode != 1 ) {
2143 R_COPY_B(Procedures[i].p.buffer, Procedures[i].p.size, UBYTE*);
2144 }
2145 else {
2146 R_SET(j, int);
2147 Procedures[i].p.buffer = Procedures[j].p.buffer;
2148 }
2149 }
2150 R_COPY_S(Procedures[i].name,UBYTE*);
2151 }
2152 AP.ProcList.message = "procedure";
2153
2154 size = (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*);
2155 R_COPY_B(AP.PreSwitchStrings, size, UBYTE**);
2156 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2157 R_COPY_S(AP.PreSwitchStrings[i],UBYTE*);
2158 }
2159
2160 org = AP.preStart;
2161 R_COPY_B(AP.preStart, AP.pSize, UBYTE*);
2162 ofs = AP.preStart - org;
2163 if ( AP.preFill ) AP.preFill += ofs;
2164 if ( AP.preStop ) AP.preStop += ofs;
2165
2166 R_COPY_S(AP.procedureExtension,UBYTE*);
2167 R_COPY_S(AP.cprocedureExtension,UBYTE*);
2168
2169 R_COPY_B(AP.PreAssignStack,AP.MaxPreAssignLevel*(LONG)sizeof(LONG),LONG*);
2170 R_COPY_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int), int*);
2171 R_COPY_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int), int*);
2172 R_COPY_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int), int*);
2173
2174#ifdef PRINTDEBUG
2175 print_P();
2176#endif
2177
2178 /*#] AP : */
2179 /*#[ AR : */
2180
2181 R_SET(ofs,LONG);
2182 if ( ofs ) {
2183 AR.infile = AR.Fscr+1;
2184 AR.outfile = AR.Fscr;
2185 AR.hidefile = AR.Fscr+2;
2186 }
2187 else {
2188 AR.infile = AR.Fscr;
2189 AR.outfile = AR.Fscr+1;
2190 AR.hidefile = AR.Fscr+2;
2191 }
2192
2193 /* #[ AR free pointers */
2194
2195 /* Parts of AR will be overwritten by data from the recovery file, therefore
2196 * dynamically allocated memory must be freed first. */
2197
2198 namebufout = AR.outfile->name;
2199 namebufhide = AR.hidefile->name;
2200 R_FREE(AR.outfile->PObuffer);
2201#ifdef WITHZLIB
2202 R_FREE(AR.outfile->zsp);
2203 R_FREE(AR.outfile->ziobuffer);
2204#endif
2205 namebufhide = AR.hidefile->name;
2206 R_FREE(AR.hidefile->PObuffer);
2207#ifdef WITHZLIB
2208 R_FREE(AR.hidefile->zsp);
2209 R_FREE(AR.hidefile->ziobuffer);
2210#endif
2211 /* no files should be opened -> nothing to do with handle */
2212
2213 /* #] AR free pointers */
2214
2215 /* outfile */
2216 R_SET(*AR.outfile, FILEHANDLE);
2217 org = (UBYTE*)AR.outfile->PObuffer;
2218 size = AR.outfile->POfull - AR.outfile->PObuffer;
2219 AR.outfile->PObuffer = (WORD*)Malloc1(AR.outfile->POsize, "PObuffer");
2220 if ( size ) {
2221 memcpy(AR.outfile->PObuffer, p, size*sizeof(WORD));
2222 p = (unsigned char*)p + size*sizeof(WORD);
2223 }
2224 ofs = (UBYTE*)AR.outfile->PObuffer - org;
2225 AR.outfile->POstop = (WORD*)((UBYTE*)AR.outfile->POstop + ofs);
2226 AR.outfile->POfill = (WORD*)((UBYTE*)AR.outfile->POfill + ofs);
2227 AR.outfile->POfull = (WORD*)((UBYTE*)AR.outfile->POfull + ofs);
2228 AR.outfile->name = namebufout;
2229#ifdef WITHPTHREADS
2230 AR.outfile->wPObuffer = AR.outfile->PObuffer;
2231 AR.outfile->wPOstop = AR.outfile->POstop;
2232 AR.outfile->wPOfill = AR.outfile->POfill;
2233 AR.outfile->wPOfull = AR.outfile->POfull;
2234#endif
2235#ifdef WITHZLIB
2236 /* zsp and ziobuffer will be allocated when used */
2237 AR.outfile->zsp = 0;
2238 AR.outfile->ziobuffer = 0;
2239#endif
2240 /* reopen old outfile */
2241#ifdef WITHMPI
2242 if(PF.me==MASTER)
2243#endif
2244 if ( AR.outfile->handle >= 0 ) {
2245 if ( CopyFile(sortfile, AR.outfile->name) ) {
2246 MesPrint("ERROR: Could not copy old output sort file %s!",sortfile);
2247 Terminate(-1);
2248 }
2249 AR.outfile->handle = ReOpenFile(AR.outfile->name);
2250 if ( AR.outfile->handle == -1 ) {
2251 MesPrint("ERROR: Could not reopen output sort file %s!",AR.outfile->name);
2252 Terminate(-1);
2253 }
2254 SeekFile(AR.outfile->handle, &AR.outfile->POposition, SEEK_SET);
2255 }
2256
2257 /* hidefile */
2258 R_SET(*AR.hidefile, FILEHANDLE);
2259 AR.hidefile->name = namebufhide;
2260 if ( AR.hidefile->PObuffer ) {
2261 org = (UBYTE*)AR.hidefile->PObuffer;
2262 size = AR.hidefile->POfull - AR.hidefile->PObuffer;
2263 AR.hidefile->PObuffer = (WORD*)Malloc1(AR.hidefile->POsize, "PObuffer");
2264 if ( size ) {
2265 memcpy(AR.hidefile->PObuffer, p, size*sizeof(WORD));
2266 p = (unsigned char*)p + size*sizeof(WORD);
2267 }
2268 ofs = (UBYTE*)AR.hidefile->PObuffer - org;
2269 AR.hidefile->POstop = (WORD*)((UBYTE*)AR.hidefile->POstop + ofs);
2270 AR.hidefile->POfill = (WORD*)((UBYTE*)AR.hidefile->POfill + ofs);
2271 AR.hidefile->POfull = (WORD*)((UBYTE*)AR.hidefile->POfull + ofs);
2272#ifdef WITHPTHREADS
2273 AR.hidefile->wPObuffer = AR.hidefile->PObuffer;
2274 AR.hidefile->wPOstop = AR.hidefile->POstop;
2275 AR.hidefile->wPOfill = AR.hidefile->POfill;
2276 AR.hidefile->wPOfull = AR.hidefile->POfull;
2277#endif
2278 }
2279#ifdef WITHZLIB
2280 /* zsp and ziobuffer will be allocated when used */
2281 AR.hidefile->zsp = 0;
2282 AR.hidefile->ziobuffer = 0;
2283#endif
2284 /* reopen old hidefile */
2285 if ( AR.hidefile->handle >= 0 ) {
2286 if ( CopyFile(hidefile, AR.hidefile->name) ) {
2287 MesPrint("ERROR: Could not copy old hide file %s!",hidefile);
2288 Terminate(-1);
2289 }
2290 AR.hidefile->handle = ReOpenFile(AR.hidefile->name);
2291 if ( AR.hidefile->handle == -1 ) {
2292 MesPrint("ERROR: Could not reopen hide file %s!",AR.hidefile->name);
2293 Terminate(-1);
2294 }
2295 SeekFile(AR.hidefile->handle, &AR.hidefile->POposition, SEEK_SET);
2296 }
2297
2298 /* store file */
2299 R_SET(pos, POSITION);
2300 if ( ISNOTZEROPOS(pos) ) {
2301 CloseFile(AR.StoreData.Handle);
2302 R_SET(AR.StoreData, FILEDATA);
2303 if ( CopyFile(storefile, FG.fname) ) {
2304 MesPrint("ERROR: Could not copy old store file %s!",storefile);
2305 Terminate(-1);
2306 }
2307 AR.StoreData.Handle = (WORD)ReOpenFile(FG.fname);
2308 SeekFile(AR.StoreData.Handle, &AR.StoreData.Position, SEEK_SET);
2309 }
2310
2311 R_SET(AR.DefPosition, POSITION);
2312 R_SET(AR.OldTime, LONG);
2313 R_SET(AR.InInBuf, LONG);
2314 R_SET(AR.InHiBuf, LONG);
2315
2316 R_SET(AR.NoCompress, int);
2317 R_SET(AR.gzipCompress, int);
2318
2319 R_SET(AR.outtohide, int);
2320
2321 R_SET(AR.GetFile, WORD);
2322 R_SET(AR.KeptInHold, WORD);
2323 R_SET(AR.BracketOn, WORD);
2324 R_SET(AR.MaxBracket, WORD);
2325 R_SET(AR.CurDum, WORD);
2326 R_SET(AR.DeferFlag, WORD);
2327 R_SET(AR.TePos, WORD);
2328 R_SET(AR.sLevel, WORD);
2329 R_SET(AR.Stage4Name, WORD);
2330 R_SET(AR.GetOneFile, WORD);
2331 R_SET(AR.PolyFun, WORD);
2332 R_SET(AR.PolyFunInv, WORD);
2333 R_SET(AR.PolyFunType, WORD);
2334 R_SET(AR.PolyFunExp, WORD);
2335 R_SET(AR.PolyFunVar, WORD);
2336 R_SET(AR.PolyFunPow, WORD);
2337 R_SET(AR.Eside, WORD);
2338 R_SET(AR.MaxDum, WORD);
2339 R_SET(AR.level, WORD);
2340 R_SET(AR.expchanged, WORD);
2341 R_SET(AR.expflags, WORD);
2342 R_SET(AR.CurExpr, WORD);
2343 R_SET(AR.SortType, WORD);
2344 R_SET(AR.ShortSortCount, WORD);
2345
2346 /* this is usually done in Process(), but sometimes FORM doesn't
2347 end up executing Process() before it uses the AR.CompressPointer,
2348 so we need to explicitely set it here. */
2349 AR.CompressPointer = AR.CompressBuffer;
2350
2351#ifdef WITHPTHREADS
2352 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2353 R_SET(AB[j]->R.wranfnpair1, int);
2354 R_SET(AB[j]->R.wranfnpair2, int);
2355 R_SET(AB[j]->R.wranfcall, int);
2356 R_SET(AB[j]->R.wranfseed, ULONG);
2357 R_SET(AB[j]->R.wranfia,ULONG*);
2358 if ( AB[j]->R.wranfia ) {
2359 R_COPY_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2, ULONG*);
2360 }
2361 }
2362#else
2363 R_SET(AR.wranfnpair1, int);
2364 R_SET(AR.wranfnpair2, int);
2365 R_SET(AR.wranfcall, int);
2366 R_SET(AR.wranfseed, ULONG);
2367 R_SET(AR.wranfia,ULONG*);
2368 if ( AR.wranfia ) {
2369 R_COPY_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2, ULONG*);
2370 }
2371#endif
2372
2373#ifdef PRINTDEBUG
2374 print_R();
2375#endif
2376
2377 /*#] AR : */
2378 /*#[ AO :*/
2379/*
2380 We copy all non-pointer variables.
2381*/
2382 l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
2383 memcpy(&(A.O.NumInBrack), p, l); p = (unsigned char*)p + l;
2384/*
2385 Now the variables in OptimizeResult
2386*/
2387 memcpy(&(A.O.OptimizeResult),p,sizeof(OPTIMIZERESULT));
2388 p = (unsigned char*)p + sizeof(OPTIMIZERESULT);
2389
2390 if ( A.O.OptimizeResult.codesize > 0 ) {
2391 R_COPY_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD),WORD *);
2392 }
2393 R_COPY_S(A.O.OptimizeResult.nameofexpr,UBYTE *);
2394/*
2395 And now the dictionaries. We know how many there are. We also know
2396 how many elements the array AO.Dictionaries should have.
2397*/
2398 if ( AO.SizeDictionaries > 0 ) {
2399 AO.Dictionaries = (DICTIONARY **)Malloc1(AO.SizeDictionaries*sizeof(DICTIONARY *),
2400 "Dictionaries");
2401 for ( i = 0; i < AO.NumDictionaries; i++ ) {
2402 R_SET(l,LONG)
2403 AO.Dictionaries[i] = DictFromBytes(p);
2404 p = (char *)p + l;
2405 }
2406 }
2407 /*#] AO :*/
2408#ifdef WITHMPI
2409 /*#[ PF : */
2410 {/*Block*/
2411 int numtasks;
2412 R_SET(numtasks, int);
2413 if(numtasks!=PF.numtasks){
2414 MesPrint("%d number of tasks expected instead of %d; use mpirun -np %d",
2415 numtasks,PF.numtasks,numtasks);
2416 if(PF.me!=MASTER)
2417 remove(RecoveryFilename());
2418 Terminate(-1);
2419 }
2420 }/*Block*/
2421 R_SET(PF.rhsInParallel, int);
2422 R_SET(PF.exprbufsize, int);
2423 R_SET(PF.log, int);
2424 /*#] PF : */
2425#endif
2426
2427#ifdef WITHPTHREADS
2428 /* read timing information of individual threads */
2429 R_SET(i, int);
2430 for ( j=1; j<AM.totalnumberofthreads; ++j ) {
2431 /* ... and correcting OldTime */
2432 AB[j]->R.OldTime = -(*((LONG*)p+j));
2433 }
2434 WriteTimerInfo((LONG*)p,(LONG *)((unsigned char*)p + i*(LONG)sizeof(LONG)));
2435 p = (unsigned char*)p + 2*i*(LONG)sizeof(LONG);
2436#endif /* ifdef WITHPTHREADS */
2437
2438 if ( fclose(fd) ) return(__LINE__);
2439
2440 M_free(buf,"recovery buffer");
2441
2442 /* cares about data in S_const */
2443 UpdatePositions();
2444 AT.SS = AT.S0;
2445/*
2446 Set the checkpoint parameter right for the next checkpoint.
2447*/
2448 AC.CheckpointStamp = TimeWallClock(1);
2449
2450 done_snapshot = 1;
2451 MesPrint("done."); fflush(0);
2452
2453 return(0);
2454}
2455
2456/*
2457 #] DoRecovery :
2458 #[ DoSnapshot :
2459*/
2460
2476static int DoSnapshot(int moduletype)
2477{
2478 GETIDENTITY
2479 FILE *fd;
2480 POSITION pos;
2481 int i, j;
2482 LONG l;
2483 WORD *w;
2484 void *adr;
2485#ifdef WITHPTHREADS
2486 LONG *longp,*longpp;
2487#endif /* ifdef WITHPTHREADS */
2488
2489 MesPrint("Saving recovery point ... %"); fflush(0);
2490#ifdef PRINTTIMEMARKS
2491 MesPrint("\n");
2492#endif
2493
2494 if ( !(fd = fopen(intermedfile, "wb")) ) return(__LINE__);
2495
2496 /* reserve space in the file for a length field */
2497 if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) return(__LINE__);
2498
2499 /* write moduletype */
2500 if ( fwrite(&moduletype, 1, sizeof(int), fd) != sizeof(int) ) return(__LINE__);
2501
2502 /*#[ AM :*/
2503
2504 /* since most values don't change during execution, AM doesn't need to be
2505 * written as a whole. all values will be correctly set when starting up
2506 * anyway. only the exceptions need to be taken care of. see MakeGlobal()
2507 * and PopVariables() in execute.c. */
2508
2509 ANNOUNCE(AM)
2510 S_WRITE_B(&AM.hparallelflag, sizeof(int));
2511 S_WRITE_B(&AM.gparallelflag, sizeof(int));
2512 S_WRITE_B(&AM.gCodesFlag, sizeof(int));
2513 S_WRITE_B(&AM.gNamesFlag, sizeof(int));
2514 S_WRITE_B(&AM.gStatsFlag, sizeof(int));
2515 S_WRITE_B(&AM.gTokensWriteFlag, sizeof(int));
2516 S_WRITE_B(&AM.gNoSpacesInNumbers, sizeof(int));
2517 S_WRITE_B(&AM.gIndentSpace, sizeof(WORD));
2518 S_WRITE_B(&AM.gUnitTrace, sizeof(WORD));
2519 S_WRITE_B(&AM.gDefDim, sizeof(int));
2520 S_WRITE_B(&AM.gDefDim4, sizeof(int));
2521 S_WRITE_B(&AM.gncmod, sizeof(WORD));
2522 S_WRITE_B(&AM.gnpowmod, sizeof(WORD));
2523 S_WRITE_B(&AM.gmodmode, sizeof(WORD));
2524 S_WRITE_B(&AM.gOutputMode, sizeof(WORD));
2525 S_WRITE_B(&AM.gCnumpows, sizeof(WORD));
2526 S_WRITE_B(&AM.gOutputSpaces, sizeof(WORD));
2527 S_WRITE_B(&AM.gOutNumberType, sizeof(WORD));
2528 S_WRITE_B(&AM.gfunpowers, sizeof(int));
2529 S_WRITE_B(&AM.gPolyFun, sizeof(WORD));
2530 S_WRITE_B(&AM.gPolyFunInv, sizeof(WORD));
2531 S_WRITE_B(&AM.gPolyFunType, sizeof(WORD));
2532 S_WRITE_B(&AM.gPolyFunExp, sizeof(WORD));
2533 S_WRITE_B(&AM.gPolyFunVar, sizeof(WORD));
2534 S_WRITE_B(&AM.gPolyFunPow, sizeof(WORD));
2535 S_WRITE_B(&AM.gProcessBucketSize, sizeof(LONG));
2536 S_WRITE_B(&AM.OldChildTime, sizeof(LONG));
2537 S_WRITE_B(&AM.OldSecTime, sizeof(LONG));
2538 S_WRITE_B(&AM.OldMilliTime, sizeof(LONG));
2539 S_WRITE_B(&AM.gproperorderflag, sizeof(int));
2540 S_WRITE_B(&AM.gThreadBucketSize, sizeof(LONG));
2541 S_WRITE_B(&AM.gSizeCommuteInSet, sizeof(int));
2542 S_WRITE_B(&AM.gThreadStats, sizeof(int));
2543 S_WRITE_B(&AM.gFinalStats, sizeof(int));
2544 S_WRITE_B(&AM.gThreadsFlag, sizeof(int));
2545 S_WRITE_B(&AM.gThreadBalancing, sizeof(int));
2546 S_WRITE_B(&AM.gThreadSortFileSynch, sizeof(int));
2547 S_WRITE_B(&AM.gProcessStats, sizeof(int));
2548 S_WRITE_B(&AM.gOldParallelStats, sizeof(int));
2549 S_WRITE_B(&AM.gSortType, sizeof(int));
2550 S_WRITE_B(&AM.gShortStatsMax, sizeof(WORD));
2551 S_WRITE_B(&AM.gIsFortran90, sizeof(int));
2552 adr = &AM.dollarzero;
2553 S_WRITE_B(&adr, sizeof(void*));
2554 S_WRITE_B(&AM.gFortran90Kind,sizeof(UBYTE *));
2555 S_WRITE_S(AM.gFortran90Kind);
2556
2557 S_WRITE_S(AM.gextrasym);
2558 S_WRITE_S(AM.ggextrasym);
2559
2560 S_WRITE_B(&AM.PrintTotalSize,sizeof(int));
2561 S_WRITE_B(&AM.fbuffersize,sizeof(int));
2562 S_WRITE_B(&AM.gOldFactArgFlag,sizeof(int));
2563 S_WRITE_B(&AM.ggOldFactArgFlag,sizeof(int));
2564
2565 S_WRITE_B(&AM.gnumextrasym,sizeof(int));
2566 S_WRITE_B(&AM.ggnumextrasym,sizeof(int));
2567 S_WRITE_B(&AM.NumSpectatorFiles,sizeof(int));
2568 S_WRITE_B(&AM.SizeForSpectatorFiles,sizeof(int));
2569 S_WRITE_B(&AM.gOldGCDflag,sizeof(int));
2570 S_WRITE_B(&AM.ggOldGCDflag,sizeof(int));
2571 S_WRITE_B(&AM.gWTimeStatsFlag, sizeof(int));
2572
2573 S_WRITE_B(&AM.Path,sizeof(UBYTE *));
2574 S_WRITE_S(AM.Path);
2575
2576 S_WRITE_B(&AM.FromStdin,sizeof(BOOL));
2577
2578 /*#] AM :*/
2579 /*#[ AC :*/
2580
2581 /* we write AC as a whole and then write all additional data step by step.
2582 * AC.DubiousList doesn't need to be treated, because it should be empty. */
2583
2584 ANNOUNCE(AC)
2585 S_WRITE_B(&AC, sizeof(struct C_const));
2586
2587 S_WRITE_NAMETREE(AC.dollarnames);
2588 S_WRITE_NAMETREE(AC.exprnames);
2589 S_WRITE_NAMETREE(AC.varnames);
2590
2591 S_WRITE_LIST(AC.ChannelList);
2592 for ( i=0; i<AC.ChannelList.num; ++i ) {
2593 S_WRITE_S(channels[i].name);
2594 }
2595
2596 ANNOUNCE(AC.FunctionList)
2597 S_WRITE_LIST(AC.FunctionList);
2598 for ( i=0; i<AC.FunctionList.num; ++i ) {
2599 /* if the function is a table */
2600 if ( functions[i].tabl ) {
2601 TABLES tabl = functions[i].tabl;
2602 S_WRITE_B(tabl, sizeof(struct TaBlEs));
2603 if ( tabl->tablepointers ) {
2604 if ( tabl->sparse ) {
2605 /* sparse tables. reserved holds number of allocated
2606 * elements. the size of an element is numind plus
2607 * TABLEEXTENSION times the size of WORD. */
2608 S_WRITE_B(tabl->tablepointers,
2609 tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION));
2610 }
2611 else {
2612 /* matrix like tables. */
2613 S_WRITE_B(tabl->tablepointers,
2614 TABLEEXTENSION*sizeof(WORD)*(tabl->totind));
2615 }
2616 }
2617 S_WRITE_B(tabl->prototype, tabl->prototypeSize);
2618 S_WRITE_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX));
2619 S_WRITE_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD));
2620 if ( tabl->sparse ) {
2621 S_WRITE_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE));
2622 S_WRITE_S(tabl->argtail);
2623 }
2624 S_WRITE_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD));
2625 if ( tabl->spare ) {
2626 TABLES spare = tabl->spare;
2627 S_WRITE_B(spare, sizeof(struct TaBlEs));
2628 if ( spare->tablepointers ) {
2629 if ( spare->sparse ) {
2630 /* sparse tables */
2631 S_WRITE_B(spare->tablepointers,
2632 spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION));
2633 }
2634 else {
2635 /* matrix like tables */
2636 S_WRITE_B(spare->tablepointers,
2637 TABLEEXTENSION*sizeof(WORD)*(spare->totind));
2638 }
2639 }
2640 S_WRITE_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX));
2641 S_WRITE_B(spare->flags, spare->numind*(LONG)sizeof(WORD));
2642 if ( spare->sparse ) {
2643 S_WRITE_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE));
2644 }
2645 S_WRITE_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD));
2646 }
2647 }
2648 }
2649
2650 ANNOUNCE(AC.ExpressionList)
2651 S_WRITE_LIST(AC.ExpressionList);
2652 for ( i=0; i<AC.ExpressionList.num; ++i ) {
2653 EXPRESSIONS ex = Expressions + i;
2654 if ( ex->renum ) {
2655 S_WRITE_B(ex->renum, sizeof(struct ReNuMbEr));
2656 /* there is one dynamically allocated buffer for struct ReNuMbEr and
2657 * symb.lo points to its beginning. the size of the buffer is not
2658 * stored anywhere but we know it is 2*sizeof(WORD)*N, where N is
2659 * the number of all vectors, indices, functions and symbols. since
2660 * funum points into the buffer at a distance 2N-[Number of
2661 * functions] from symb.lo (see GetTable() in store.c), we can
2662 * calculate the buffer size by some pointer arithmetic. the size is
2663 * then written to the file. */
2664 l = ex->renum->funnum - ex->renum->symb.lo;
2665 l += ex->renum->funnum - ex->renum->func.lo;
2666 S_WRITE_B(&l, sizeof(size_t));
2667 S_WRITE_B(ex->renum->symb.lo, l);
2668 }
2669 if ( ex->bracketinfo ) {
2670 S_WRITE_B(ex->bracketinfo, sizeof(BRACKETINFO));
2671 S_WRITE_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
2672 S_WRITE_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD));
2673 }
2674 if ( ex->newbracketinfo ) {
2675 S_WRITE_B(ex->newbracketinfo, sizeof(BRACKETINFO));
2676 S_WRITE_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
2677 S_WRITE_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD));
2678 }
2679 /* don't need to write ex->renumlists */
2680 if ( ex->inmem ) {
2681 /* size of the inmem buffer has to be determined. we use the fact
2682 * that the end of an expression is marked by a zero. */
2683 w = ex->inmem;
2684 while ( *w++ ) ;
2685 l = w - ex->inmem;
2686 S_WRITE_B(&l, sizeof(size_t));
2687 S_WRITE_B(ex->inmem, l);
2688 }
2689 }
2690
2691 ANNOUNCE(AC.IndexList)
2692 S_WRITE_LIST(AC.IndexList);
2693 S_WRITE_LIST(AC.SetElementList);
2694 S_WRITE_LIST(AC.SetList);
2695 S_WRITE_LIST(AC.SymbolList);
2696 S_WRITE_LIST(AC.VectorList);
2697
2698 ANNOUNCE(AC.TableBaseList)
2699 S_WRITE_LIST(AC.TableBaseList);
2700 for ( i=0; i<AC.TableBaseList.num; ++i ) {
2701 /* see struct dbase in minos.h */
2702 if ( tablebases[i].iblocks ) {
2703 S_WRITE_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks * sizeof(INDEXBLOCK*));
2704 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
2705 if ( tablebases[i].iblocks[j] ) {
2706 S_WRITE_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK));
2707 }
2708 }
2709 }
2710 if ( tablebases[i].nblocks ) {
2711 S_WRITE_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks * sizeof(NAMESBLOCK*));
2712 for ( j=0; j<tablebases[i].info.numberofnamesblocks; ++j ) {
2713 if ( tablebases[i].nblocks[j] ) {
2714 S_WRITE_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK));
2715 }
2716 }
2717 }
2718 S_WRITE_S(tablebases[i].name);
2719 S_WRITE_S(tablebases[i].fullname);
2720 S_WRITE_S(tablebases[i].tablenames);
2721 }
2722
2723 ANNOUNCE(AC.cbufList)
2724 S_WRITE_LIST(AC.cbufList);
2725 for ( i=0; i<AC.cbufList.num; ++i ) {
2726 S_WRITE_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD));
2727 /* see inicbufs in comtool.c */
2728 S_WRITE_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*));
2729 S_WRITE_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)));
2730 if ( cbuf[i].boomlijst ) {
2731 S_WRITE_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*(LONG)sizeof(COMPTREE));
2732 }
2733 }
2734
2735 S_WRITE_LIST(AC.AutoSymbolList);
2736 S_WRITE_LIST(AC.AutoIndexList);
2737 S_WRITE_LIST(AC.AutoVectorList);
2738 S_WRITE_LIST(AC.AutoFunctionList);
2739
2740 S_WRITE_NAMETREE(AC.autonames);
2741
2742 ANNOUNCE(AC.Streams)
2743 S_WRITE_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM));
2744 for ( i=0; i<AC.NumStreams; ++i ) {
2745 if ( AC.Streams[i].inbuffer ) {
2746 S_WRITE_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer);
2747 }
2748 S_WRITE_S(AC.Streams[i].FoldName);
2749 S_WRITE_S(AC.Streams[i].name);
2750 }
2751
2752 if ( AC.termstack ) {
2753 S_WRITE_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG));
2754 }
2755
2756 if ( AC.termsortstack ) {
2757 S_WRITE_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG));
2758 }
2759
2760 S_WRITE_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD));
2761
2762 if ( AC.IfHeap ) {
2763 S_WRITE_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1));
2764 S_WRITE_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1));
2765 }
2766
2767 l = AC.iStop - AC.iBuffer + 2;
2768 S_WRITE_B(AC.iBuffer, l);
2769
2770 if ( AC.LabelNames ) {
2771 S_WRITE_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)));
2772 for ( i=0; i<AC.NumLabels; ++i ) {
2773 S_WRITE_S(AC.LabelNames[i]);
2774 }
2775 }
2776
2777 S_WRITE_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD));
2778
2779 if ( AC.termsumcheck ) {
2780 S_WRITE_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD));
2781 }
2782
2783 S_WRITE_B(AC.WildcardNames, AC.WildcardBufferSize);
2784
2785 if ( AC.tokens ) {
2786 l = AC.toptokens - AC.tokens;
2787 if ( l ) {
2788 S_WRITE_B(AC.tokens, l);
2789 }
2790 }
2791
2792 S_WRITE_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD));
2793
2794 S_WRITE_S(AC.Fortran90Kind);
2795
2796#ifdef WITHPTHREADS
2797 if ( AC.inputnumbers ) {
2798 S_WRITE_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)));
2799 }
2800#endif /* ifdef WITHPTHREADS */
2801
2802 if ( AC.IfSumCheck ) {
2803 S_WRITE_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1));
2804 }
2805 if ( AC.CommuteInSet ) {
2806 S_WRITE_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1));
2807 }
2808
2809 S_WRITE_S(AC.CheckpointRunAfter);
2810 S_WRITE_S(AC.CheckpointRunBefore);
2811
2812 S_WRITE_S(AC.extrasym);
2813
2814 /*#] AC :*/
2815 /*#[ AP :*/
2816
2817 /* we write AP as a whole and then write all additional data step by step. */
2818
2819 ANNOUNCE(AP)
2820 S_WRITE_B(&AP, sizeof(struct P_const));
2821
2822 S_WRITE_LIST(AP.DollarList);
2823 for ( i=0; i<AP.DollarList.num; ++i ) {
2824 DOLLARS d = Dollars + i;
2825 S_WRITE_DOLLAR(Dollars[i]);
2826 if ( d->nfactors > 1 ) {
2827 S_WRITE_B(&(d->factors),sizeof(FACDOLLAR)*d->nfactors);
2828 for ( j = 0; j < d->nfactors; j++ ) {
2829 if ( d->factors[j].size > 0 ) {
2830 S_WRITE_B(&(d->factors[i].where),sizeof(WORD)*(d->factors[j].size+1));
2831 }
2832 }
2833 }
2834 }
2835
2836 S_WRITE_LIST(AP.PreVarList);
2837 for ( i=0; i<AP.PreVarList.num; ++i ) {
2838 /* there is one dynamically allocated buffer in struct pReVaR holding
2839 * the strings name, value and several argnames. the size of the buffer
2840 * can be calculated by adding up their string lengths. */
2841 l = strlen((char*)PreVar[i].name) + 1;
2842 if ( PreVar[i].value ) {
2843 l += strlen((char*)(PreVar[i].name+l)) + 1;
2844 }
2845 for ( j=0; j<PreVar[i].nargs; ++j ) {
2846 l += strlen((char*)(PreVar[i].name+l)) + 1;
2847 }
2848 S_WRITE_B(&l, sizeof(size_t));
2849 S_WRITE_B(PreVar[i].name, l);
2850 }
2851
2852 ANNOUNCE(AP.LoopList)
2853 S_WRITE_LIST(AP.LoopList);
2854 for ( i=0; i<AP.LoopList.num; ++i ) {
2855 S_WRITE_B(DoLoops[i].p.buffer, DoLoops[i].p.size);
2856 if ( DoLoops[i].type == ONEEXPRESSION ) {
2857 /* do loops with an expression keep this expression in a dynamically
2858 * allocated buffer in dollarname */
2859 S_WRITE_S(DoLoops[i].dollarname);
2860 }
2861 }
2862
2863 S_WRITE_LIST(AP.ProcList);
2864 for ( i=0; i<AP.ProcList.num; ++i ) {
2865 if ( Procedures[i].p.size ) {
2866 if ( Procedures[i].loadmode != 1 ) {
2867 S_WRITE_B(Procedures[i].p.buffer, Procedures[i].p.size);
2868 }
2869 else {
2870 for ( j=0; j<AP.ProcList.num; ++j ) {
2871 if ( Procedures[i].p.buffer == Procedures[j].p.buffer ) {
2872 break;
2873 }
2874 }
2875 if ( j == AP.ProcList.num ) {
2876 MesPrint("Error writing procedures to recovery file!");
2877 }
2878 S_WRITE_B(&j, sizeof(int));
2879 }
2880 }
2881 S_WRITE_S(Procedures[i].name);
2882 }
2883
2884 S_WRITE_B(AP.PreSwitchStrings, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*));
2885 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2886 S_WRITE_S(AP.PreSwitchStrings[i]);
2887 }
2888
2889 S_WRITE_B(AP.preStart, AP.pSize);
2890
2891 S_WRITE_S(AP.procedureExtension);
2892 S_WRITE_S(AP.cprocedureExtension);
2893
2894 S_WRITE_B(AP.PreAssignStack, AP.MaxPreAssignLevel*(LONG)sizeof(LONG));
2895 S_WRITE_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int));
2896 S_WRITE_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int));
2897 S_WRITE_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int));
2898
2899 /*#] AP :*/
2900 /*#[ AR :*/
2901
2902 ANNOUNCE(AR)
2903 /* to remember which entry in AR.Fscr corresponds to the infile */
2904 l = AR.infile - AR.Fscr;
2905 S_WRITE_B(&l, sizeof(LONG));
2906
2907 /* write the FILEHANDLEs */
2908 S_WRITE_B(AR.outfile, sizeof(FILEHANDLE));
2909 l = AR.outfile->POfull - AR.outfile->PObuffer;
2910 if ( l ) {
2911 S_WRITE_B(AR.outfile->PObuffer, l*sizeof(WORD));
2912 }
2913 S_WRITE_B(AR.hidefile, sizeof(FILEHANDLE));
2914 l = AR.hidefile->POfull - AR.hidefile->PObuffer;
2915 if ( l ) {
2916 S_WRITE_B(AR.hidefile->PObuffer, l*sizeof(WORD));
2917 }
2918
2919 S_WRITE_B(&AR.StoreData.Fill, sizeof(POSITION));
2920 if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
2921 S_WRITE_B(&AR.StoreData, sizeof(FILEDATA));
2922 }
2923
2924 S_WRITE_B(&AR.DefPosition, sizeof(POSITION));
2925
2926 l = TimeCPU(1); l = -l;
2927 S_WRITE_B(&l, sizeof(LONG));
2928
2929 ANNOUNCE(AR.InInBuf)
2930 S_WRITE_B(&AR.InInBuf, sizeof(LONG));
2931 S_WRITE_B(&AR.InHiBuf, sizeof(LONG));
2932
2933 S_WRITE_B(&AR.NoCompress, sizeof(int));
2934 S_WRITE_B(&AR.gzipCompress, sizeof(int));
2935
2936 S_WRITE_B(&AR.outtohide, sizeof(int));
2937
2938 S_WRITE_B(&AR.GetFile, sizeof(WORD));
2939 S_WRITE_B(&AR.KeptInHold, sizeof(WORD));
2940 S_WRITE_B(&AR.BracketOn, sizeof(WORD));
2941 S_WRITE_B(&AR.MaxBracket, sizeof(WORD));
2942 S_WRITE_B(&AR.CurDum, sizeof(WORD));
2943 S_WRITE_B(&AR.DeferFlag, sizeof(WORD));
2944 S_WRITE_B(&AR.TePos, sizeof(WORD));
2945 S_WRITE_B(&AR.sLevel, sizeof(WORD));
2946 S_WRITE_B(&AR.Stage4Name, sizeof(WORD));
2947 S_WRITE_B(&AR.GetOneFile, sizeof(WORD));
2948 S_WRITE_B(&AR.PolyFun, sizeof(WORD));
2949 S_WRITE_B(&AR.PolyFunInv, sizeof(WORD));
2950 S_WRITE_B(&AR.PolyFunType, sizeof(WORD));
2951 S_WRITE_B(&AR.PolyFunExp, sizeof(WORD));
2952 S_WRITE_B(&AR.PolyFunVar, sizeof(WORD));
2953 S_WRITE_B(&AR.PolyFunPow, sizeof(WORD));
2954 S_WRITE_B(&AR.Eside, sizeof(WORD));
2955 S_WRITE_B(&AR.MaxDum, sizeof(WORD));
2956 S_WRITE_B(&AR.level, sizeof(WORD));
2957 S_WRITE_B(&AR.expchanged, sizeof(WORD));
2958 S_WRITE_B(&AR.expflags, sizeof(WORD));
2959 S_WRITE_B(&AR.CurExpr, sizeof(WORD));
2960 S_WRITE_B(&AR.SortType, sizeof(WORD));
2961 S_WRITE_B(&AR.ShortSortCount, sizeof(WORD));
2962
2963#ifdef WITHPTHREADS
2964 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2965 S_WRITE_B(&(AB[j]->R.wranfnpair1), sizeof(int));
2966 S_WRITE_B(&(AB[j]->R.wranfnpair2), sizeof(int));
2967 S_WRITE_B(&(AB[j]->R.wranfcall), sizeof(int));
2968 S_WRITE_B(&(AB[j]->R.wranfseed), sizeof(ULONG));
2969 S_WRITE_B(&(AB[j]->R.wranfia),sizeof(ULONG *));
2970 if ( AB[j]->R.wranfia ) {
2971 S_WRITE_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2);
2972 }
2973 }
2974#else
2975 S_WRITE_B(&(AR.wranfnpair1), sizeof(int));
2976 S_WRITE_B(&(AR.wranfnpair2), sizeof(int));
2977 S_WRITE_B(&(AR.wranfcall), sizeof(int));
2978 S_WRITE_B(&(AR.wranfseed), sizeof(ULONG));
2979 S_WRITE_B(&(AR.wranfia),sizeof(ULONG *));
2980 if ( AR.wranfia ) {
2981 S_WRITE_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2);
2982 }
2983#endif
2984
2985 /*#] AR :*/
2986 /*#[ AO :*/
2987/*
2988 We copy all non-pointer variables.
2989*/
2990 ANNOUNCE(AO)
2991 l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
2992 S_WRITE_B(&(A.O.NumInBrack),l);
2993/*
2994 Now the variables in OptimizeResult
2995*/
2996 S_WRITE_B(&(A.O.OptimizeResult),sizeof(OPTIMIZERESULT));
2997 if ( A.O.OptimizeResult.codesize > 0 ) {
2998 S_WRITE_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD));
2999 }
3000 S_WRITE_S(A.O.OptimizeResult.nameofexpr);
3001/*
3002 And now the dictionaries.
3003 We write each dictionary to a buffer and get the size of that buffer.
3004 Then we write the size and the buffer.
3005*/
3006 for ( i = 0; i < AO.NumDictionaries; i++ ) {
3007 l = DictToBytes(AO.Dictionaries[i],(UBYTE *)(AT.WorkPointer));
3008 S_WRITE_B(&l,sizeof(LONG));
3009 S_WRITE_B(AT.WorkPointer,l);
3010 }
3011
3012 /*#] AO :*/
3013 /*#[ PF :*/
3014#ifdef WITHMPI
3015 S_WRITE_B(&PF.numtasks, sizeof(int));
3016 S_WRITE_B(&PF.rhsInParallel, sizeof(int));
3017 S_WRITE_B(&PF.exprbufsize, sizeof(int));
3018 S_WRITE_B(&PF.log, sizeof(int));
3019#endif
3020 /*#] PF :*/
3021
3022#ifdef WITHPTHREADS
3023
3024 ANNOUNCE(GetTimerInfo)
3025/*
3026 write timing information of individual threads
3027*/
3028 i = GetTimerInfo(&longp,&longpp);
3029 S_WRITE_B(&i, sizeof(int));
3030 S_WRITE_B(longp, i*(LONG)sizeof(LONG));
3031 S_WRITE_B(&i, sizeof(int));
3032 S_WRITE_B(longpp, i*(LONG)sizeof(LONG));
3033
3034#endif
3035
3036 S_FLUSH_B /* because we will call fwrite() directly in the following code */
3037
3038 /* save length of data at the beginning of the file */
3039 ANNOUNCE(file length)
3040 SETBASEPOSITION(pos, (ftell(fd)));
3041 fseek(fd, 0, SEEK_SET);
3042 if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) return(__LINE__);
3043 fseek(fd, BASEPOSITION(pos), SEEK_SET);
3044
3045 ANNOUNCE(file close)
3046 if ( fclose(fd) ) return(__LINE__);
3047#ifdef WITHMPI
3048 if ( PF.me == MASTER ) {
3049#endif
3050/*
3051 copy store file if necessary
3052*/
3053 ANNOUNCE(copy store file)
3054 if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
3055 if ( CopyFile(FG.fname, storefile) ) return(__LINE__);
3056 }
3057/*
3058 copy sort file if necessary
3059*/
3060 ANNOUNCE(copy sort file)
3061 if ( AR.outfile->handle >= 0 ) {
3062 if ( CopyFile(AR.outfile->name, sortfile) ) return(__LINE__);
3063 }
3064/*
3065 copy hide file if necessary
3066*/
3067 ANNOUNCE(copy hide file)
3068 if ( AR.hidefile->handle >= 0 ) {
3069 if ( CopyFile(AR.hidefile->name, hidefile) ) return(__LINE__);
3070 }
3071#ifdef WITHMPI
3072 }
3073 /*
3074 * For ParFORM, the renaming will be performed after the master got
3075 * all recovery files from the slaves.
3076 */
3077#else
3078/*
3079 make the intermediate file the recovery file
3080*/
3081 ANNOUNCE(rename intermediate file)
3082 if ( rename(intermedfile, recoveryfile) ) return(__LINE__);
3083
3084 done_snapshot = 1;
3085
3086 MesPrint("done."); fflush(0);
3087#endif
3088
3089#ifdef PRINTDEBUG
3090 print_M();
3091 print_C();
3092 print_P();
3093 print_R();
3094#endif
3095
3096 return(0);
3097}
3098
3099/*
3100 #] DoSnapshot :
3101 #[ DoCheckpoint :
3102*/
3103
3108void DoCheckpoint(int moduletype)
3109{
3110 int error;
3111 LONG timestamp = TimeWallClock(1);
3112#ifdef WITHMPI
3113 if(PF.me == MASTER){
3114#endif
3115 if ( timestamp - AC.CheckpointStamp >= AC.CheckpointInterval ) {
3116 char argbuf[20];
3117 int retvalue = 0;
3118 if ( AC.CheckpointRunBefore ) {
3119 size_t l, l2;
3120 char *str;
3121 l = strlen(AC.CheckpointRunBefore);
3122 NumToStr((UBYTE*)argbuf, AC.CModule);
3123 l2 = strlen(argbuf);
3124 str = (char*)Malloc1(l+l2+2, "callbefore");
3125 strcpy(str, AC.CheckpointRunBefore);
3126 *(str+l) = ' ';
3127 strcpy(str+l+1, argbuf);
3128 retvalue = system(str);
3129 M_free(str, "callbefore");
3130 if ( retvalue ) {
3131 MesPrint("Script returned error -> no recovery file will be created.");
3132 }
3133 }
3134#ifdef WITHMPI
3135 /* Confirm slaves to make snapshots. */
3136 PF_BroadcastNumber(retvalue == 0);
3137#endif
3138 if ( retvalue == 0 ) {
3139 if ( (error = DoSnapshot(moduletype)) ) {
3140 MesPrint("Error creating recovery files: %d", error);
3141 }
3142#ifdef WITHMPI
3143 {
3144 int i;
3145 /*get recovery files from slaves:*/
3146 for(i=1; i<PF.numtasks;i++){
3147 FILE *fd;
3148 const char *tmpnam = PF_recoveryfile('m', i, 1);
3149 fd = fopen(tmpnam, "w");
3150 if(fd == NULL){
3151 MesPrint("Error opening recovery file for slave %d",i);
3152 Terminate(-1);
3153 }/*if(fd == NULL)*/
3154 retvalue=PF_RecvFile(i,fd);
3155 if(retvalue<=0){
3156 MesPrint("Error receiving recovery file from slave %d",i);
3157 Terminate(-1);
3158 }/*if(retvalue<=0)*/
3159 fclose(fd);
3160 }/*for(i=0; i<PF.numtasks;i++)*/
3161 /*
3162 * Make the intermediate files the recovery files.
3163 */
3164 ANNOUNCE(rename intermediate file)
3165 for ( i = 0; i < PF.numtasks; i++ ) {
3166 const char *src = PF_recoveryfile('m', i, 1);
3167 const char *dst = PF_recoveryfile('m', i, 0);
3168 if ( rename(src, dst) ) {
3169 MesPrint("Error renaming recovery file %s -> %s", src, dst);
3170 }
3171 }
3172 done_snapshot = 1;
3173 MesPrint("done."); fflush(0);
3174 }
3175#endif
3176 }
3177 if ( AC.CheckpointRunAfter ) {
3178 size_t l, l2;
3179 char *str;
3180 l = strlen(AC.CheckpointRunAfter);
3181 NumToStr((UBYTE*)argbuf, AC.CModule);
3182 l2 = strlen(argbuf);
3183 str = (char*)Malloc1(l+l2+2, "callafter");
3184 strcpy(str, AC.CheckpointRunAfter);
3185 *(str+l) = ' ';
3186 strcpy(str+l+1, argbuf);
3187 retvalue = system(str);
3188 M_free(str, "callafter");
3189 if ( retvalue ) {
3190 MesPrint("Error calling script after recovery.");
3191 }
3192 }
3193 AC.CheckpointStamp = TimeWallClock(1);
3194 }
3195#ifdef WITHMPI
3196 else{/* timestamp - AC.CheckpointStamp < AC.CheckpointInterval*/
3197 /* The slaves don't need to make snapshots. */
3199 }
3200 }/*if(PF.me == MASTER)*/
3201 else{/*Slave*/
3202 int i;
3203 /* Check if the slave needs to make a snapshot. */
3204 if ( PF_BroadcastNumber(0) ) {
3205 error = DoSnapshot(moduletype);
3206 if(error == 0){
3207 FILE *fd;
3208 /*
3209 * Send the recovery file to the master. Note that no renaming
3210 * has been performed and what we have to send is actually sitting
3211 * in the intermediate file.
3212 */
3213 fd = fopen(intermedfile, "r");
3214 i=PF_SendFile(MASTER, fd);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3215 if(fd == NULL)
3216 Terminate(-1);
3217 fclose(fd);
3218 if(i<=0)
3219 Terminate(-1);
3220 /*Now the slave need not the recovery file so remove it:*/
3221 remove(intermedfile);
3222 }
3223 else{
3224 /*send the error tag to the master:*/
3225 PF_SendFile(MASTER,NULL);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3226 Terminate(-1);
3227 }
3228 done_snapshot = 1;
3229 }/*if(tag=PF_DATA_MSGTAG)*/
3230 }/*if(PF.me != MASTER)*/
3231#endif
3232}
3233
3234/*
3235 #] DoCheckpoint :
3236*/
void InitRecovery()
Definition checkpoint.c:399
int CheckRecoveryFile()
Definition checkpoint.c:278
void DoCheckpoint(int moduletype)
void DeleteRecoveryFile()
Definition checkpoint.c:333
int DoRecovery(int *moduletype)
char * RecoveryFilename()
Definition checkpoint.c:364
LONG TimeWallClock(WORD)
Definition tools.c:3476
int CopyFile(char *, char *)
Definition tools.c:1101
LONG TimeCPU(WORD)
Definition tools.c:3550
int PF_RecvFile(int from, FILE *fd)
Definition parallel.c:4245
LONG PF_BroadcastNumber(LONG x)
Definition parallel.c:2083
int PF_SendFile(int to, FILE *fd)
Definition parallel.c:4207
BRACKETINDEX * indexbuffer
Definition structs.h:329
WORD * bracketbuffer
Definition structs.h:330
LONG BufferSize
Definition structs.h:949
WORD * numdum
Definition structs.h:946
LONG * NumTerms
Definition structs.h:945
COMPTREE * boomlijst
Definition structs.h:948
WORD ** rhs
Definition structs.h:943
WORD ** lhs
Definition structs.h:942
WORD * Buffer
Definition structs.h:939
LONG * CanCommu
Definition structs.h:944
UBYTE * dollarname
Definition structs.h:853
PRELOAD p
Definition structs.h:849
UBYTE * name
Definition structs.h:850
WORD * renumlists
Definition structs.h:397
char * message
Definition structs.h:206
int numclear
Definition structs.h:212
int size
Definition structs.h:209
int numglobal
Definition structs.h:210
int maxnum
Definition structs.h:208
int num
Definition structs.h:207
void * lijst
Definition structs.h:205
int numtemp
Definition structs.h:211
WORD type
Definition structs.h:252
WORD balance
Definition structs.h:251
WORD left
Definition structs.h:249
WORD number
Definition structs.h:253
LONG name
Definition structs.h:247
WORD parent
Definition structs.h:248
WORD right
Definition structs.h:250
LONG clearnodefill
Definition structs.h:280
LONG namefill
Definition structs.h:273
LONG nodesize
Definition structs.h:270
LONG oldnamefill
Definition structs.h:274
LONG namesize
Definition structs.h:272
WORD headnode
Definition structs.h:281
LONG nodefill
Definition structs.h:271
UBYTE * namebuffer
Definition structs.h:267
NAMENODE * namenode
Definition structs.h:265
LONG clearnamefill
Definition structs.h:279
LONG globalnamefill
Definition structs.h:276
LONG oldnodefill
Definition structs.h:275
LONG globalnodefill
Definition structs.h:278
VARRENUM indi
Definition structs.h:181
WORD * symnum
Definition structs.h:185
WORD * funnum
Definition structs.h:188
WORD * vecnum
Definition structs.h:187
VARRENUM func
Definition structs.h:183
WORD * indnum
Definition structs.h:186
VARRENUM symb
Definition structs.h:180
VARRENUM vect
Definition structs.h:182
UBYTE * pointer
Definition structs.h:692
UBYTE * pname
Definition structs.h:696
UBYTE * FoldName
Definition structs.h:694
UBYTE * buffer
Definition structs.h:691
UBYTE * name
Definition structs.h:695
WORD * pattern
Definition structs.h:356
WORD * buffers
Definition structs.h:364
struct TaBlEs * spare
Definition structs.h:363
WORD * tablepointers
Definition structs.h:350
int prototypeSize
Definition structs.h:369
UBYTE * argtail
Definition structs.h:361
COMPTREE * boomlijst
Definition structs.h:360
LONG reserved
Definition structs.h:366
int MaxTreeSize
Definition structs.h:376
WORD bufferssize
Definition structs.h:378
WORD * flags
Definition structs.h:359
WORD * prototype
Definition structs.h:355
MINMAX * mm
Definition structs.h:358
int numind
Definition structs.h:370
LONG totind
Definition structs.h:365
int sparse
Definition structs.h:373
WORD * hi
Definition structs.h:168
WORD * lo
Definition structs.h:167
WORD * start
Definition structs.h:166
int nargs
Definition structs.h:796
int wildarg
Definition structs.h:797
UBYTE * argnames
Definition structs.h:795
UBYTE * value
Definition structs.h:794
UBYTE * name
Definition structs.h:793
int blnce
Definition structs.h:298
int right
Definition structs.h:296
int parent
Definition structs.h:294
int value
Definition structs.h:297
int left
Definition structs.h:295