diff --git a/C/agc.c b/C/agc.c index cb43a65ba..8e4a97ed5 100644 --- a/C/agc.c +++ b/C/agc.c @@ -31,6 +31,14 @@ static char SccsId[] = "@(#)agc.c 1.3 3/15/90"; STATIC_PROTO(void RestoreEntries, (PropEntry *)); STATIC_PROTO(void ConvDBList, (Term, char *,CELL)); +static int agc_calls; + +static Int agc_collected; + +static Int tot_agc_time = 0; /* total time spent in GC */ + +static Int tot_agc_recovered = 0; /* number of heap objects in all garbage collections */ + #define AtomMarkedBit 1 static inline void @@ -335,6 +343,7 @@ clean_atoms(void) #endif *patm = at->NextOfAE; atm = at->NextOfAE; + agc_collected += SizeOfBlock((char *)at); FreeCodeSpace((char *)at); } } @@ -353,6 +362,7 @@ clean_atoms(void) #endif *patm = at->NextOfAE; atm = at->NextOfAE; + agc_collected += SizeOfBlock((char *)at); FreeCodeSpace((char *)at); } } @@ -361,8 +371,59 @@ clean_atoms(void) void atom_gc(void) { + int gc_verbose = is_gc_verbose(); + int gc_trace = 0; + + + Int time_start, agc_time; + if (GetValue(AtomGcTrace) != TermNil) + gc_trace = 1; + agc_calls++; + agc_collected = 0; + if (gc_trace) { + YP_fprintf(YP_stderr, "[agc]\n"); + } else if (gc_verbose) { + YP_fprintf(YP_stderr, "[AGC] Start of atom garbage collection %d:\n", agc_calls); + } + time_start = cputime(); + /* get the number of active registers */ + YAPEnterCriticalSection(); mark_stacks(); mark_atoms(); clean_atoms(); - LookupAtom("!"); + YAPLeaveCriticalSection(); + agc_time = cputime()-time_start; + tot_agc_time += agc_time; + tot_agc_recovered += agc_collected; + if (gc_verbose) { + YP_fprintf(YP_stderr, "[AGC] collected %d bytes.\n", agc_collected); + YP_fprintf(YP_stderr, "[AGC] GC %d took %g sec, total of %g sec doing GC so far.\n", agc_calls, (double)agc_time/1000, (double)tot_agc_time/1000); + } +} + +static Int +p_atom_gc(void) +{ +#ifndef FIXED_STACKS + atom_gc(); +#endif /* FIXED_STACKS */ + return(TRUE); +} + +static Int +p_inform_agc(void) +{ + Term tn = MkIntegerTerm(tot_agc_time); + Term tt = MkIntegerTerm(agc_calls); + Term ts = MkIntegerTerm(tot_agc_recovered); + + return(unify(tn, ARG2) && unify(tt, ARG1) && unify(ts, ARG3)); + +} + +void +init_agc(void) +{ + InitCPred("$atom_gc", 0, p_atom_gc, 0); + InitCPred("$inform_agc", 3, p_inform_agc, 0); } diff --git a/C/grow.c b/C/grow.c index fe55a50be..d4a621e43 100644 --- a/C/grow.c +++ b/C/grow.c @@ -963,4 +963,5 @@ InitGrowPreds(void) InitCPred("$inform_heap_overflows", 2, p_inform_heap_overflows, SafePredFlag); InitCPred("$inform_stack_overflows", 2, p_inform_stack_overflows, SafePredFlag); init_gc(); + init_agc(); } diff --git a/C/heapgc.c b/C/heapgc.c index 512da34d1..3f1188aee 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -3096,19 +3096,9 @@ p_gc(void) return(TRUE); } -static Int -p_atom_gc(void) -{ -#ifndef FIXED_STACKS - atom_gc(); -#endif /* FIXED_STACKS */ - return(TRUE); -} - void init_gc(void) { InitCPred("$gc", 0, p_gc, 0); InitCPred("$inform_gc", 3, p_inform_gc, 0); - InitCPred("$atom_gc", 0, p_atom_gc, 0); } diff --git a/H/Yapproto.h b/H/Yapproto.h index eac0b2dd0..1934d2981 100644 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -10,7 +10,7 @@ * File: Yap.proto * * mods: * * comments: Function declarations for YAP * -* version: $Id: Yapproto.h,v 1.19 2002-06-04 18:21:55 vsc Exp $ * +* version: $Id: Yapproto.h,v 1.20 2002-06-05 03:59:50 vsc Exp $ * *************************************************************************/ /* prototype file for Yap */ @@ -64,6 +64,7 @@ Term STD_PROTO(Module_Name, (CODEADDR)); /* agc.c */ void STD_PROTO(atom_gc, (void)); +void STD_PROTO(init_agc, (void)); /* alloc.c */ int STD_PROTO(SizeOfBlock,(CODEADDR)); diff --git a/pl/utils.yap b/pl/utils.yap index 22f61b0c0..96a71fe71 100644 --- a/pl/utils.yap +++ b/pl/utils.yap @@ -397,9 +397,10 @@ statistics :- '$inform_stack_overflows'(NOfSO,TotSOTime), '$inform_trail_overflows'(NOfTO,TotTOTime), '$inform_gc'(NOfGC,TotGCTime,TotGCSize), - '$statistics'(Runtime,CPUtime,Walltime,HpSpa,HpInUse,HpMax,TrlSpa, TrlInUse,TrlMax,StkSpa, GlobInU, LocInU,GlobMax,LocMax,NOfHO,TotHOTime,NOfSO,TotSOTime,NOfTO,TotTOTime,NOfGC,TotGCTime,TotGCSize). + '$inform_agc'(NOfAGC,TotAGCTime,TotAGCSize), + '$statistics'(Runtime,CPUtime,Walltime,HpSpa,HpInUse,HpMax,TrlSpa, TrlInUse,TrlMax,StkSpa, GlobInU, LocInU,GlobMax,LocMax,NOfHO,TotHOTime,NOfSO,TotSOTime,NOfTO,TotTOTime,NOfGC,TotGCTime,TotGCSize,NOfAGC,TotAGCTime,TotAGCSize). -'$statistics'(Runtime,CPUtime,Walltime,HpSpa,HpInUse,_HpMax,TrlSpa, TrlInUse,_TrlMax,StkSpa, GlobInU, LocInU,GlobMax,LocMax,NOfHO,TotHOTime,NOfSO,TotSOTime,NOfTO,TotTOTime,NOfGC,TotGCTime,TotGCSize) :- +'$statistics'(Runtime,CPUtime,Walltime,HpSpa,HpInUse,_HpMax,TrlSpa, TrlInUse,_TrlMax,StkSpa, GlobInU, LocInU,GlobMax,LocMax,NOfHO,TotHOTime,NOfSO,TotSOTime,NOfTO,TotTOTime,NOfGC,TotGCTime,TotGCSize,NOfAGC,TotAGCTime,TotAGCSize) :- TotalMemory is HpSpa+StkSpa+TrlSpa, '$format'(user_error,"memory (total)~t~d bytes~35+~n", [TotalMemory]), '$format'(user_error," program space~t~d bytes~35+", [HpSpa]), @@ -427,6 +428,9 @@ statistics :- TotGCTimeF is float(TotGCTime)/1000, '$format'(user_error,"~t~3f~12+ sec. for ~w garbage collections which collected ~d bytes~n", [TotGCTimeF,NOfGC,TotGCSize]), + TotAGCTimeF is float(TotAGCTime)/1000, + '$format'(user_error,"~t~3f~12+ sec. for ~w atom garbage collections which collected ~d bytes~n", + [TotAGCTimeF,NOfAGC,TotAGCSize]), RTime is float(Runtime)/1000, '$format'(user_error,"~t~3f~12+ sec. runtime~n", [RTime]), CPUTime is float(CPUtime)/1000, @@ -434,7 +438,7 @@ statistics :- WallTime is float(Walltime)/1000, '$format'(user_error,"~t~3f~12+ sec. elapsed time~n~n", [WallTime]), fail. -'$statistics'(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_). +'$statistics'(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_). statistics(runtime,[T,L]) :- '$runtime'(T,L).