ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/contrib/gauge/Model/hread_model.c

This is hread_model.c in view mode; [Download] [Up]

#if (!defined(lint) && !defined(SABER)) 
static char *rcsid = "$Header: /ufs/comp/mei/TestPCN/onprofile/IFModel/Model/RCS/hread_model.c,v 1.12 1992/01/25 00:29:58 mei Exp $";
#endif

/* AERO_MESG */

#include <stdio.h>
#include <strings.h>
#ifdef HISTOGRAM
#include <Xsw/Xsw.h>
#include <Gauge/Gauge.h>
#endif

#ifndef _MODELP_H
#include "modelP.h"
#endif

#define MODEL_FILE 0
#define COUNTER_FILE 1

char *Buffer;

/********************************************************/
/* Name : expand_buffer                                 */
/* Content : buffer is reused by all routines and when  */
/*  buffer is needed whose size exceed current allocated*/
/*  size, the old buffer is freed and a new one is mal- */
/*  loced. Note, the buffer_size is a static declaration*/
/* Date : OLD routines                                  */
/********************************************************/
expand_buffer(size,where)
     unsigned int size;
     char *where;
{
  static int buffer_size = 0;
  if (buffer_size < size) {
    if (buffer_size != 0)
      Free(Buffer);
    Buffer = checkmalloc(size,where);
    buffer_size = size;
  }
}

/********************************************************/
/* Name : line_type                                     */
/* Content : the first character from a line in *cnt    */
/*  file is retrieve (this will tell what that line is) */
/* Date : OLD routines                                  */
/********************************************************/
int line_type(model)
     FILE *model;
{
  char type[2];
  int scan_arg;
  while (1)
  {
      scan_arg = fscanf(model," %1s ",type);
      if (scan_arg == EOF)
      {
	  return EOF;
      }
      else if (scan_arg < 1)
      {
	  return UNKNOWN;
      }
      else if (type[0] == '#')
      {
	  /*
	   * Lines starting with a # are comment lines.
	   * Note: The _must_ be something on the line after the #
	   * or this will skip the next line in the .cnt file.
	   */
	  fscanf(model,"%*[^\n] ");
      }
      else
      {
	  return (int) type[0];
      }
  }
}

/********************************************************/
/* Name : read_version_number                           */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
/*ARGSUSED*/
read_version_number(hPtr,file,file_type,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
     int file_type;
{
  int version;
  int scan_args = fscanf(file," %d ", &version);

  
  if (scan_args != 1) {
    sprintf(TextBuffer,"Invalid version number in counter file at line %d",linecnt);
    GaugeError("read_version_number",TextBuffer);
  }
  if (file_type == COUNTER_FILE && version != CURRENT_COUNTER_VERSION) {
    sprintf(TextBuffer,"Invalid counter version number %d",version);
    GaugeError("read_version_number",TextBuffer);
  }
  if (file_type == MODEL_FILE && version != CURRENT_MODEL_VERSION) {
    sprintf(TextBuffer,"Invalid model version number %d",version);
    GaugeError("read_version_number",TextBuffer);
  }
}

/********************************************************/
/* Name : read_guard_stats                              */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
/*ARGSUSED*/
read_guard_stats(hPtr,module,models,linecnt)
     Histo *hPtr;
     char *module;
     FILE *models;
     int linecnt;
{
  fscanf(models,"%*[^\n] ");
}

/********************************************************/
/* Name : read_procedure_model                          */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_procedure_model(hPtr,type,module,models,linecnt)
     Histo *hPtr;
     char type;
     char *module;
     FILE *models;
     int linecnt;
{
  char name[MAX_NAME];
  int size;
  int idle, copy, suspend;
  char visibility;
  Procedure *pPtr;
  /* MAX_NAME chars read */
  int scan_args = fscanf(models," %49s %d",name,&size); 

  if (scan_args != 2) {
    sprintf(TextBuffer,"Invalid procedure declaration in model file at line %d",linecnt);
    GaugeError("read_procedure_model",TextBuffer);
  }
  if (fscanf(models," %c %d %d %d",&visibility,&idle,&copy,&suspend) != 4) {
    sprintf(TextBuffer,"Invalid procedure declaration in model file at line %d",linecnt);
    GaugeError("read_procedure_model",TextBuffer);
  }

  pPtr = (Procedure *) 
    checkmalloc(sizeof(Procedure)+(type == FOREIGN_PROCEDURE ? 0 : (size-1))*sizeof(Clause),
		"read_procedure_model");
  insert_procedure(hPtr->modules,module,name,pPtr);

  pPtr->total=(ProcedureProfileData *) NULL;

  pPtr->name = strcpy(checkmalloc(strlen(name)+1,"read_procedure_model"),name);
  pPtr->arguments = atoi(rindex(name,'/')+1); /* Get number of arguments */
  pPtr->callers = (RGraph *) NULL;
  pPtr->size = size;
  pPtr->type = type;
  pPtr->offsets.idle = idle;
  pPtr->offsets.copy = copy;
  pPtr->offsets.suspend = suspend;
  pPtr->visible = (visibility == 'V') ? 1 : 0;
  pPtr->id = (visibility == 'V') ? hPtr->info.procedure_cnt++ : hPtr->info.procedure_cnt;
/* hui 2/10 */
  initialize_procpernode(hPtr,pPtr);
  pPtr->mod_ptr = lookup_module(hPtr->modules,module);
}

/********************************************************/
/* Name : read_clause_model                             */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_clause_model(hPtr,module,models,linecnt)
     Histo *hPtr;
     char *module;
     FILE *models;
     int linecnt;
{
  char name[MAX_NAME];
  Procedure *proc;
  Foreign *fPtr;
  Clause *clause_model;
  int clause_number, i;
  int foreign_cnt;
  /* MAX_NAME chars read */

  if (fscanf(models," %49s ",name) != 1) 
    goto format_error;

  clause_number = atoi(rindex(name,'/')+1);
  *(rindex(name,'/')) = '\0';
  if ((proc = find_procedure(hPtr->modules,module,name)) == (Procedure *) NULL) {
    sprintf(TextBuffer,"Clause definition for undefined procedure %s:%s at line %d",module,name,linecnt);
    GaugeError("read_clause_model",TextBuffer);
  }

  clause_model = proc->clauses+clause_number;

  for (i = 0; i < INSTR_CLASSES ; i++)
    if (fscanf(models," %f ",clause_model->model.success+i) != 1)
      goto format_error;
  for (i = 0; i < INSTR_CLASSES ; i++)
    if (fscanf(models," %f ",clause_model->model.failure+i) != 1)
      goto format_error;

  if (fscanf(models," %d %d ",
	     &(clause_model->commit_offset), &foreign_cnt) != 2)
    goto format_error;

  fPtr = clause_model->foreigns =
    (Foreign *) checkmalloc(sizeof(Foreign) * (foreign_cnt+1),"read_clause_model");
			    
  for (i = 0 ; i < foreign_cnt ; i++) {
    if (fscanf(models," %s %d ",name, &(fPtr->timer)) != 2)
      goto format_error;
    if ((fPtr->procedure = find_procedure(hPtr->modules,module,name)) == NULL) {
      sprintf(TextBuffer,"Reference to undefined foreign %s at line %d",name,linecnt);
      GaugeError("read_clause_model",TextBuffer);
    }
    fPtr++;
  }
  fPtr->procedure = (Procedure *) NULL;
  fPtr->timer = -1;
  clause_model->body_goals = -1;
  clause_model->calls = (Procedure **) NULL;
  clause_model->proc_ptr = proc;
  initialize_claupernode(hPtr,clause_model);
  return TRUE;

  format_error:
  sprintf(TextBuffer,"Invalid clause definition at line %d",linecnt);
  GaugeError("read_clause_model",TextBuffer);
}

/********************************************************/
/* Name : read_call_graph                               */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_call_graph(hPtr,module,models,linecnt)
Histo *hPtr;
char *module;
FILE *models;
int linecnt;
{
    char name[1024];
    Procedure *parent, *child;
    Clause *cPtr;
    Procedure **callees;
    RGraph *ctemp;
    int goals, non_foreign_goals;
    int clause_number;
    
    if (fscanf(models," %d %1024s",&goals,name) != 2) {
	sprintf(TextBuffer,"Invalid call graph declaration at line %d",linecnt);
	GaugeError("read_call_graph",TextBuffer);
    }
    
#ifdef DONT_INCLUDE  
    if (goals > 0)
    {
	/*
	 * HACK -- Steve Tuecke, 11/6/92
	 *
	 * Done for PCN 2.0.
	 *
	 * Do not do anything with the rest of the call graph
	 * line (i.e., the procedures that this one calls),
	 * since the call graph cannot handle intermodule
	 * calls yet.  (Call target may not yet be in the database.)
	 */
	fscanf(models,"%*[^\n] ");
	goals = 0;
    }
#endif /* DONT_INCLUDE */
    
    clause_number = atoi(rindex(name,'/')+1);
    *(rindex(name,'/')) = '\0';
    if ((parent = find_procedure(hPtr->modules,module,name)) == (Procedure *) NULL) {
	sprintf(TextBuffer,"Call graph on undefined procedure %s at line %d",name,linecnt);
	GaugeError("read_call_graph",TextBuffer);
    }
    cPtr = parent->clauses+clause_number;
    cPtr->body_goals = goals;

    if (goals > 0)
    {
	callees = (Procedure **) checkmalloc(sizeof(Procedure *) * goals,
					     "call graph");
	cPtr->calls = callees;

	/*
	 * HACKED by Steve Tuecke (11/11/92) to only read foreign
	 * procedure calls into the call graph
	 */
	non_foreign_goals = 0;
	while (goals--)
	{
	    if (fscanf(models," %1024s",name) != 1) {
		sprintf(TextBuffer,"Invalid call graph declaration at line %d",linecnt);
		GaugeError("read_call_graph",TextBuffer);
	    }

	    if (index(name, ':') == NULL)
	    {
		/* This is a foreign call */
		if ((child = find_procedure(hPtr->modules,module,name)) == (Procedure *) NULL) {
		    sprintf(TextBuffer,"Call graph on undefined procedure %s at line %d",name,linecnt);
		    GaugeError("read_call_graph",TextBuffer);
		}
		*(callees++) = child;
		ctemp = (RGraph *) checkmalloc(sizeof(RGraph),"read_call_graph");
		ctemp->clause_ptr = cPtr;
		ctemp->next = child->callers;
		child->callers = ctemp;
	    }
	    else
	    {
		non_foreign_goals++;
	    }
	}
	cPtr->body_goals -= non_foreign_goals;
	if (cPtr->body_goals <= 0)
	{
	    /* Free the call graph space back up it unused */
	    free(cPtr->calls);
	}
#ifdef DONT_INCLUDE
	/* This is the original code to read in all call targets */
	while (goals--)
	{
	    if (fscanf(models," %1024s",name) != 1) {
		sprintf(TextBuffer,"Invalid call graph declaration at line %d",linecnt);
		GaugeError("read_call_graph",TextBuffer);
	    }
	    
	    if ((child = find_procedure(hPtr->modules,module,name)) == (Procedure *) NULL) {
		sprintf(TextBuffer,"Call graph on undefined procedure %s at line %d",name,linecnt);
		GaugeError("read_call_graph",TextBuffer);
	    }
	    *(callees++) = child;
	    ctemp = (RGraph *) checkmalloc(sizeof(RGraph),"read_call_graph");
	    ctemp->clause_ptr = cPtr;
	    ctemp->next = child->callers;
	    child->callers = ctemp;
	}
#endif /* DONT_INCLUDE */	
    }
}
    
/********************************************************/
/* Name : read_counter_values                           */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_counter_values(hPtr,file,mPtr,node,snap_no,snapname,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
     Module **mPtr;
     int *node,*snap_no;
     char *snapname;
{
  int counters;

  char module[MAX_NAME];    /* MAX_NAME chars */

  /*
    Make sure we skip over the space that follows the number
    of counters
    */
  if (fscanf(file," %49s %d %d %49s %d%*c",snapname,snap_no,node,module,&counters) != 5) 
    goto format_error;
  if ((*mPtr = lookup_module(hPtr->modules,module)) == (Module *) NULL)
    goto format_error;
  expand_buffer(sizeof(long) * counters, "read_counter_values");
  (*mPtr)->ncounters = counters;
  if (fread(Buffer, sizeof(long), counters, file) != counters)
    goto format_error;
  (hPtr->nodes[*node].machine->byte_swapper)(Buffer,counters,SWAP_COUNTERS,
					     hPtr->architecture->ticks_per_second);
  return TRUE;
 format_error:
  sprintf(TextBuffer,"Invalid counter values in counter file at line %d",linecnt);
  GaugeError("read_counter_values",TextBuffer);
}

/********************************************************/
/* Name : read_timer_values                             */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_timer_values(hPtr,file,mPtr,node,snap_no,snapname,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
     int *node,*snap_no;
     char *snapname;
     Module **mPtr;
{
  int timers;
/* unsigned long sec, usec; */
  char module[MAX_NAME];   

  /*
    Make sure we skip over the space that follows the number
    of timers
    */
  if (fscanf(file," %49s %d %d %49s %d%*c",snapname,snap_no,node,module,&timers) != 5) 
    goto format_error;
  if ((*mPtr = lookup_module(hPtr->modules,module)) == (Module *) NULL)
    goto format_error;

  expand_buffer(sizeof(double) * timers, "read_timer_values");
  (*mPtr)->ntimers = timers;

  if (fread(Buffer, sizeof(gauge_timer), timers, file) != timers)
    goto format_error;
  (hPtr->nodes[*node].machine->byte_swapper)(Buffer,timers,SWAP_TIMERS,
					     hPtr->architecture->ticks_per_second);
  return TRUE;

 format_error:
  sprintf(TextBuffer,"Invalid timer values in counter file at line %d",linecnt);
  GaugeError("read_timer_values",TextBuffer);
}

/********************************************************/
/* Name : lookup_arch                                   */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
struct arch_descriptor *lookup_arch(hPtr,node)
     Histo *hPtr;
     int node;
{ struct arch_descriptor *sPtr = hPtr->architecture;
  struct arch_descriptor *ePtr = sPtr + hPtr->machine_types;

  while (sPtr < ePtr)
    if (sPtr->node_range.low <= node && node <= sPtr->node_range.hi)
      return sPtr;
    else
      sPtr++;
  sprintf(TextBuffer,"Could not find architecture entry");
  GaugeError("arch_descriptor",TextBuffer);

}

/********************************************************/
/* Name : read_processors                               */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_processors(hPtr,file,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
{
  int i, node;
  int scan_args = fscanf(file," %d %d %d %d",
			 &(hPtr->info.node_cnt),
			 &(hPtr->info.first_node), 
			 &(hPtr->info.last_node),
			 &(hPtr->machine_types)); 
  if (scan_args != 4) 
    goto format_error;

  hPtr->nodes =
    (Node *) checkmalloc(sizeof(Node) * hPtr->info.node_cnt,"read_histogram");
  hPtr->architecture =  (struct arch_descriptor *)
    checkmalloc(sizeof(struct arch_descriptor) * hPtr->machine_types,"read_histogram");
  
  for (i = 0 ; i < hPtr->machine_types ; i++) {
    scan_args = fscanf(file, " %s %d %d ",
		       hPtr->architecture[i].host_name,
		       &(hPtr->architecture[i].node_range.low),
		       &(hPtr->architecture[i].node_range.hi));
    if (scan_args != 3) 
      goto format_error;
    load_arch_dbase(hPtr,hPtr->architecture+i);
  }

  for (node = 0 ; node < hPtr->info.node_cnt ; node++) {
    hPtr->nodes[node].node_no = node;
  hPtr->nodes[node].total=(ProcedureProfileData *) NULL;

  hPtr->nodes[node].bar.pattern = "default";
  hPtr->nodes[node].machine = lookup_arch(hPtr,node);
  hPtr->nodes[node].stats = (struct node_stats *) NULL;
  }

  if (hPtr->info.last_node > hPtr->info.node_cnt - 1) {
    sprintf(TextBuffer,"Invalid processor range");
    GaugeError("read_processor",TextBuffer);
  }
  return TRUE;
 
  format_error:
  sprintf(TextBuffer,"Invalid processor declaration in counter file at line %d",linecnt);
  GaugeError("read_processor",TextBuffer);
}

/********************************************************/
/* Name : set_execution_time                            */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
set_execution_time(hPtr, timer_low_word, timer_hi_word)
Histo *hPtr;
unsigned long timer_low_word;
unsigned long timer_hi_word;
{ 
    gauge_timer timer;
    double seconds;
    
    timer.low_word = timer_low_word;
    timer.hi_word = timer_hi_word;
    
    timer_secs(timer,hPtr->nodes[0].machine->ticks_per_second,&seconds);
    hPtr->info.mins = (int) seconds / 60;
    hPtr->info.secs = (int) seconds % 60;
    hPtr->info.msecs = (seconds - (int) seconds) * 1000;

}

/********************************************************/
/* Name : read_node_stats                               */
/* Content : */
/* Date : OLD routines                                  */
/********************************************************/
read_node_stats(hPtr,file,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
{
  int node,i;
  double seconds;
  gauge_timer run_time,gc_time;
  int snap_no;
  char snapname[MAX_NAME];

  if (fscanf(file," %49s %d %d ",snapname,&snap_no,&node) != 3) {
    sprintf(TextBuffer,"Invalid node statistics at line %d",linecnt);
    GaugeError("read_node_stats",TextBuffer);
  }
  if (node >= hPtr->info.node_cnt) {
    sprintf(TextBuffer,"Invalid node statistics at line %d",linecnt);
    GaugeError("read_node_stats",TextBuffer);
  }
/** hui 12/13 a node's snap_table entry**/
  if(hPtr->nodes[node].stats == (struct node_stats *) NULL) {
    hPtr->nodes[node].stats = (struct node_stats *)
      checkmalloc(sizeof(struct node_stats) * hPtr->info.snap_cnt
        ,"read_node_stats");
    for( i=0;i<hPtr->info.snap_cnt;i++)
        hPtr->nodes[node].stats[i].used=FALSE;
  }

  if (fscanf(file," %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu ",
     &(run_time.low_word), &(run_time.hi_word),
     &(gc_time.low_word), &(gc_time.hi_word),
     &(hPtr->nodes[node].stats[snap_no].gc_count),
     &(hPtr->nodes[node].stats[snap_no].send_small),
     &(hPtr->nodes[node].stats[snap_no].send_big),
     &(hPtr->nodes[node].stats[snap_no].send_length),
     &(hPtr->nodes[node].stats[snap_no].rcv_small),
     &(hPtr->nodes[node].stats[snap_no].rcv_big),
     &(hPtr->nodes[node].stats[snap_no].rcv_length)) != 11) {
    sprintf(TextBuffer,"Invalid node statistics at line %d",linecnt);
    GaugeError("read_node_stats",TextBuffer);
  }
  else hPtr->nodes[node].stats[snap_no].used=TRUE;

  timer_secs(run_time,hPtr->nodes[node].machine->ticks_per_second,&seconds);
  hPtr->nodes[node].stats[snap_no].mins = ((int) seconds) / 60;
  hPtr->nodes[node].stats[snap_no].secs = ((int) seconds) % 60;
  hPtr->nodes[node].stats[snap_no].msecs = (seconds - (int) seconds) * 1000;

  timer_secs(gc_time,hPtr->nodes[node].machine->ticks_per_second,&seconds);
  hPtr->nodes[node].stats[snap_no].gc_mins = ((int) seconds) / 60;
  hPtr->nodes[node].stats[snap_no].gc_secs = ((int) seconds) % 60;
  hPtr->nodes[node].stats[snap_no].gc_msecs = (seconds - (int) seconds) * 1000;
}

/********************************************************/
/* Name : read_a_term                                   */
/* Content : */
/* Date :                                  */
/********************************************************/
char *read_a_term(file,linecnt)
     FILE *file;
     int linecnt;
{
   static char term[MAX_NAME];
   if( fscanf(file," %49s",term) != 1) {
    sprintf(TextBuffer,"Invalid start line at line %d",linecnt);
    GaugeError("read_a_term",TextBuffer);
   }
   return term;
}

/********************************************************/
/* Name : read_model                                    */
/* Content : */
/* Date :                                  */
/********************************************************/
read_model(hPtr,file,linecnt)
     Histo *hPtr;
     FILE *file;
     int linecnt;
{
  int type;
  char module[MAX_NAME];
  char endname[MAX_NAME];

  if (fscanf(file," %s",module) != 1) {
    sprintf(TextBuffer,"Invalid model file format at line %d\n",linecnt);
    GaugeError("read_model",TextBuffer);
  }

  hPtr->info.module_cnt++;
  
#ifdef DONT_INCLUDE 
  /*
   * Steve Tuecke, 11/25/92
   * What is this doing here?
   * It overflow the TextBuffer when there are a lot of modules.
   */
  sprintf(TextBuffer+strlen(TextBuffer),"  Reading model for module: %s\n",module);
#endif

  while ((type = line_type(file)) != EOF) {
    linecnt += 1;
    switch (type) {
    case VERSION:
      read_version_number(hPtr,file,MODEL_FILE,linecnt);
      break;
    case PCN_PARALLEL:
    case PCN_IMPLICATION:
    case FOREIGN_PROCEDURE:
      read_procedure_model(hPtr,type,module,file,linecnt);
      break;
    case CLAUSE:
      read_clause_model(hPtr,module,file,linecnt);
      break;
    case CALL_GRAPH:
      read_call_graph(hPtr,module,file,linecnt);
      break;
    case GUARD_STATS:
      read_guard_stats(hPtr,module,file,linecnt);
      break;
    case END:
      if ((fscanf(file," model %s",endname) != 1) ||
	  strcmp(endname,module)) 
	goto error;
      else
	return linecnt;
    case UNKNOWN:
    default:
      goto error;
    }/* switch */
  }/* while */
 error:
  sprintf(TextBuffer,"Invalid model file format (%c) at line %d",type,linecnt);
  GaugeError("read_model",TextBuffer);
}

/********************************************************/
/* Name : is_model                                      */
/* Content : */
/* Date :                                  */
/********************************************************/
is_model(term)
     char term[];
{
  if(strcmp(term,"model")==0)
       return TRUE;
       else return FALSE;
}

/********************************************************/
/* Name : read_counters                                 */
/* Content : */
/* Date :                                  */
/********************************************************/
read_counters(hPtr,file,linecnt)
     Histo *hPtr;
     FILE *file;
     int  linecnt;
{
  int type;
  int snap_cnt,low_node,hi_node;
  unsigned long timer_low_word, timer_hi_word;
  Module *mPtr;  
  int node_no, snap_no;
  static char snapname[MAX_NAME];
  char *assign_counter_values(), *assign_timer_values();
  AssignArg args;

if (fscanf(file," %lu %lu %d %d %d %*s",
	   &timer_low_word, &timer_hi_word,
	   &low_node,&hi_node,&snap_cnt) != 5) {
   sprintf(TextBuffer,
     "Invalid start counters format at line %d", linecnt);
   GaugeError("read_counters",TextBuffer);
}

/* set the total execution time */
set_execution_time(hPtr,timer_low_word, timer_hi_word);

/* set the hPtr and args structure */
hPtr->info.snap_cnt=args.snap_cnt=snap_cnt; 
args.hPtr = hPtr;
	
init_all_snapFixArrays(hPtr);

while ((type = line_type(file)) != EOF) {
    linecnt += 1;
    switch (type) {
    case COUNTER: 
/*malloc for mPtr is in read_counter_values*/
      read_counter_values(hPtr,file,&mPtr,&node_no,&snap_no,snapname,linecnt);
      args.buff = Buffer; /* new one each time */
      args.node_no = node_no;
/*may have duplicate copying but avoids string check*/
      strcpy(hPtr->info.snap[snap_no].name,snapname);
      args.snapname = snapname;
      args.snap_no = snap_no;
      map_table(mPtr->procedures,assign_counter_values,&args);
      insert_snaptable(mPtr,node_no,snap_no,args.snapPtr);
      break;
    case TIMER:
      read_timer_values(hPtr,file,&mPtr,&node_no,&snap_no,snapname,linecnt);
      args.buff = Buffer;
      args.node_no = node_no;
      args.snapname = snapname;
      args.snap_no = snap_no;
      map_table(mPtr->procedures,assign_timer_values,&args);
      break;
    case PER_NODE_STATS:
      read_node_stats(hPtr,file,linecnt);
      break;
    case END:
      if(strcmp(read_a_term(file,linecnt),"counter")==0)
         return linecnt;
         else
            goto counter_error;
    case UNKNOWN:
    default:
      goto counter_error;
    }
  } /* while */

return TRUE;

counter_error:
  sprintf(TextBuffer,"Invalid counter file format at line %d",linecnt);
  GaugeError("read_counters",TextBuffer);
}


/********************************************************/
/* Name : read_counters_file                            */
/* Content : */
/* Date :                                  */
/********************************************************/
read_counters_file(hPtr,file)
     Histo *hPtr;
     FILE *file;
{
  int type;
  int linecnt = 0;
  int end_seen = 0;
  char counterfile[MAX_NAME];
  char endname[MAX_NAME];

  if ((line_type(file) != START) ||
      fscanf(file," profile %s ",counterfile) != 1) 
    goto error;

  hPtr->info.reductions=hPtr->info.suspensions=0;
  hPtr->info.procedure_cnt = 0;

  while ((type = line_type(file)) != EOF) {
    linecnt += 1;
    switch (type) {
    case VERSION:
      read_version_number(hPtr,file,COUNTER_FILE,linecnt);
      break;
    case NODES:
      read_processors(hPtr,file,linecnt);
      break;
    case START:
      if( is_model(read_a_term(file,linecnt)) )
         linecnt = read_model(hPtr,file,linecnt);
         else
             linecnt = read_counters(hPtr,file,linecnt);  
      break;
    case END:
      if ((fscanf(file," profile %s",endname) != 1) ||
	  strcmp(endname,counterfile)) 
	goto error;
      else
	end_seen = 1;
      break;
    case UNKNOWN:
    default:
      goto error;
    }
  }

  if ( end_seen)
    return TRUE;

 error:
  sprintf(TextBuffer,"Invalid counter file format at line %d",linecnt);
  GaugeError("read_counters_file",TextBuffer);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.