/* debug.c

 Functions for debugging and collecting statistics.

 */

#include "debug.h"
#include "dataStructures.h"
#include <sys/time.h>
#include <sys/resource.h>

double getTime(void)
{
  struct rusage rbuf;
  double userTime;
  double systemTime;

  getrusage(RUSAGE_SELF,&rbuf);
  userTime = rbuf.ru_utime.tv_sec + (rbuf.ru_utime.tv_usec/1E6);
  systemTime = rbuf.ru_stime.tv_sec + (rbuf.ru_stime.tv_usec/1E6);

  return (userTime+systemTime);

  return 0.0;
}

void startTimer(TimerInfo *ti)
{
 struct rusage rbuf;
 struct timeval tval;

 getrusage(RUSAGE_SELF,&rbuf);
 gettimeofday(&tval,NULL);

 ti->user = rbuf.ru_utime.tv_sec + (rbuf.ru_utime.tv_usec/1E6);
 ti->system = rbuf.ru_stime.tv_sec + (rbuf.ru_stime.tv_usec/1E6);
 ti->wall = tval.tv_sec + (tval.tv_usec/1E6);
}

void endTimer(TimerInfo *ti)
{
 struct rusage rbuf;
 struct timeval tval;
 TimerInfo ti2;

 getrusage(RUSAGE_SELF,&rbuf);
 gettimeofday(&tval,NULL);

 ti2.user = rbuf.ru_utime.tv_sec + (rbuf.ru_utime.tv_usec/1E6);
 ti2.system = rbuf.ru_stime.tv_sec + (rbuf.ru_stime.tv_usec/1E6);
 ti2.wall = tval.tv_sec + (tval.tv_usec/1E6);
 
 ti->user = ti2.user - (ti->user);
 ti->system = ti2.system - (ti->system);
 ti->wall = ti2.wall - (ti->wall);
}

void logGcInfo(char *title, int exhaustive)
{
  GEN(unsigned int i;)

 fprintf(LOG_HANDLE,"GcInfo(%s)",title);
 
#ifdef GENERATIONS
 fprintf(LOG_HANDLE,"  [%1d]:", gcInfo.currentGeneration);
#endif

 STATS(fprintf(LOG_HANDLE, "\nWords::\tAlloc: %7d\tLiveW: %7d\n",
	       gcInfo.nWordsAllocated, gcInfo.nLiveWords));
 STATS(fprintf(LOG_HANDLE, "Objects::\tLive: %7d\tC: %7d\tTrav: %7d\n",
	       gcInfo.nLiveObjects, gcInfo.nCObjects,
	       gcInfo.nTraversedObjects));

 STATS(fprintf(LOG_HANDLE, "\t\tRoots: %7d\tPinned: %7d\n", gcInfo.nRoots,
	       gcInfo.nPinnedObjects));

 STATS(fprintf(LOG_HANDLE,"Roots::\tFalse: %7d\tDevious: %7d\tDups: %7d\n",
	       gcInfo.nFalseRoots,gcInfo.nDeviousRoots,gcInfo.nDuplicates));

 STATS(fprintf(LOG_HANDLE,"Pages::\tTotal: %5d\tUsed: %5d\tAllocd: %5d\tSys: %6d\tPinned: %5d\n",
	 gcInfo.nPages, gcInfo.nPagesInUse, gcInfo.nPagesAllocated,
	       gcInfo.nSystemPages, gcInfo.nPinnedPages));

#ifdef GENERATIONS
 STATS(fprintf(LOG_HANDLE,"Generations(Pages):: "));
 for(i=0;i<NUM_GENERATIONS;i++)
   {
     STATS(fprintf(LOG_HANDLE,"%1d(%6d), ",i,gcInfo.generation[i].nPages));
   }
 STATS(fprintf(LOG_HANDLE,"\n"));

 STATS(fprintf(LOG_HANDLE,"     (Collections)::-1(%6d), ",
	       gcInfo.nBasicCollections));
 for(i=0;i<NUM_GENERATIONS;i++)
   {
     STATS(fprintf(LOG_HANDLE,"%1d(%6d), ", i,
		   gcInfo.generation[i].nCollections));
   }
 STATS(fprintf(LOG_HANDLE,"\n")); 
 
#endif

 STATS(fprintf(LOG_HANDLE, "Collection: %7d, (Unused Words: %8d)\n", 
	       gcInfo.nCollections, gcInfo.nWastedSpace));
 STATS(LOG_ACCUM("Collector Time",gcInfo.collectorTime));
 STATS(fprintf(LOG_HANDLE,"\n"));

 if(!exhaustive) 
   return;

 fprintf(LOG_HANDLE,"Collection Boundary = %d\n", gcInfo.collectionBoundary);

 fprintf(LOG_HANDLE,"stackBottom = %p\n", gcInfo.stackBottom);
 fprintf(LOG_HANDLE,"stackTop = %p\n",gcInfo.stackTop);
 fprintf(LOG_HANDLE,"clearedStackBottom = %p \n",gcInfo.clearedStackBottom);
 fprintf(LOG_HANDLE,"clearedStackTop = %p \n",gcInfo.clearedStackTop);
 fprintf(LOG_HANDLE,"staticBoundary = %p\n",gcInfo.staticBoundary);
 fprintf(LOG_HANDLE,"heap = %p\n", gcInfo.heap);
 fprintf(LOG_HANDLE,"heapEnd = %p\n", gcInfo.heapEnd);
 fprintf(LOG_HANDLE,"heapSize = %d\n",gcInfo.heapSize);
 fprintf(LOG_HANDLE,"block Head = %p\n",gcInfo.blockHead);
 fprintf(LOG_HANDLE,"block Tail = %p\n",gcInfo.blockTail);
 fprintf(LOG_HANDLE,"ImplicitQueue:\n");
 fprintf(LOG_HANDLE,"C-Objects = %p\n",gcInfo.cObjects);
 fprintf(LOG_HANDLE,"explicit Queue = %p\n",gcInfo.explicitQueue);
 fprintf(LOG_HANDLE,"from Space = %p\n", &gcInfo.fromSpaceList);
 fprintf(LOG_HANDLE,"to Space = %p\n", &gcInfo.toSpaceList);
 fprintf(LOG_HANDLE,"free List = %p\n", &gcInfo.freeList);
 fprintf(LOG_HANDLE,"pinned Page List = %p\n", &gcInfo.pinnedPageList);
 BLACKLIST(fprintf(LOG_HANDLE,"black List = %p\n", &gcInfo.blackList));

 fprintf(LOG_HANDLE,"\nGlobal pointers not in gcInfo:\n");
 fprintf(LOG_HANDLE,"\tAllocPtr = %p\n",gcAllocPtr);
 
}

void gcStartup(void)
{
 
}

void gcShutdown(void)
{
 END_TIMER_ALWAYS(gcInfo.totalTime);

 fprintf(LOG_HANDLE,"%10d\t",gcInfo.heapSize); /* In words. */
 fprintf(LOG_HANDLE,"%5d\t",gcInfo.nCollections);
 fprintf(LOG_HANDLE,"\t%8d\t", gcInfo.nAllocCalls);
 LOG_TIMER_ACCUM_ALWAYS(gcInfo.totalTime,gcInfo.tAllocTime);

} 

/* EOF: debug.c */

/* (c) Frederick Smith, Greg Morrisett.
 *     October 1998, all rights reserved.
 *
 *
 *              Copyright 1990-1993 Digital Equipment Corporation
 *                         All Rights Reserved
 *
 * Permission to use, copy, and modify this software and its documentation is
 * hereby granted only under the following terms and conditions.  Both the
 * above copyright notice and this permission notice must appear in all copies
 * of the software, derivative works or modified versions, and any portions
 * thereof, and both notices must appear in supporting documentation.
 *
 * Users of this software agree to the terms and conditions set forth herein,
 * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
 * right and license under any changes, enhancements or extensions made to the
 * core functions of the software, including but not limited to those affording
 * compatibility with other hardware or software environments, but excluding
 * applications which incorporate this software.  Users further agree to use
 * their best efforts to return to Digital any such changes, enhancements or
 * extensions that they make and inform Digital of noteworthy uses of this
 * software.  Correspondence should be provided to Digital at:
 * 
 *                       Director of Licensing
 *                       Western Research Laboratory
 *                       Digital Equipment Corporation
 *                       250 University Avenue
 *                       Palo Alto, California  94301  
 * 
 * This software may be distributed (but not offered for sale or transferred
 * for compensation) to third parties, provided such third parties agree to
 * abide by the terms and conditions of this notice.  
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
