ftp.nice.ch/pub/next/unix/developer/pcn.2.0.s.tar.gz#/src/runtime/upshot.c

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

/*
 * PCN Abstract Machine Emulator
 * Authors:     Steve Tuecke and Ian Foster
 *              Argonne National Laboratory
 *
 * Please see the DISCLAIMER file in the top level directory of the
 * distribution regarding the provisions under which this software
 * is distributed.
 *
 * upshot.c	-  Upshot support routines.
 *
 * This version uses a very simple scheme.  It allocates a fixed-length
 * memory buffer, fills in the memory, and then writes the memory out
 * to a file.
 */

#include "pcn.h"

#ifdef UPSHOT

#include "usc.h"

#ifndef DEFAULT_UPSHOT_FILE
		/* base file name for upshot output log file */
#define DEFAULT_UPSHOT_FILE		"log"
#endif

#ifndef DEFAULT_UPSHOT_LOG_SIZE
		/* maximum number of log events */
#define DEFAULT_UPSHOT_LOG_SIZE		10000
#endif

typedef struct log_struct {
  int_t task_id;
  int_t event;
  int_t ii_data;
  int_t tind;
  usc_time_t time; 
} log_t;

static log_t *log_table;
static log_t *log_index;
static log_t *end_table;

static void internal_log_event();


/*
 * _p_init_upshot()
 *
 * Initialize the Upshot log event tracing if _p_upshot is TRUE.
 *
 * Allocate memory for a log structure of _p_upshot_log_size entries.
 */
void _p_init_upshot()
{
    if (_p_upshot_file[0] != '\0')
	_p_upshot = TRUE;
    else
	strcpy(_p_upshot_file, DEFAULT_UPSHOT_FILE);

    if (_p_upshot_log_size >= 0)
	_p_upshot == TRUE;
    else
	_p_upshot_log_size = DEFAULT_UPSHOT_LOG_SIZE;
    
    if (!_p_upshot)
	return;
    
#ifndef USC_PRIMITIVES_DEFINED
    if (_p_host)
    {
	fprintf(_p_stdout, "Warning: Upshot: Logging timers not available on this architecture\n");
	fflush(stdout);
    }
    _p_upshot = FALSE;
    return;
#endif	

    /* Initialize the usc timers */
    _p_usc_init();
    	    
    if ( (log_table = (log_t *) malloc(_p_upshot_log_size * sizeof(log_t)) )
	== (log_t *) NULL )
    {
	_p_malloc_error();
    }

    log_index = log_table;
    end_table = log_table + _p_upshot_log_size;

} /* _p_init_upshot() */


/*
 * _p_write_upshot_log()
 *
 * Write out the log buffer to a file.  The file name is composed
 * of _p_upshot_file and the node number.
 *
 * Mods:  Possibly use open() because it's faster.
 */
void _p_write_upshot_log()
{
    FILE *fp;
    char fname[MAX_PATH_LENGTH];
    log_t *logp;

    if (!_p_upshot)
	return;

    if (_p_host)
    {
	fprintf(_p_stdout, "Writing Upshot log files: %s.*\n", _p_upshot_file);
	fflush(_p_stdout);
    }

    sprintf(fname, "%s.%ld", _p_upshot_file, (long) _p_my_id);
    if( (fp = fopen(fname, "w")) == (FILE *) NULL )
    {
	fprintf(_p_stdout, "Warning: Upshot: Error opening Upshot log file: \"%s\"\n",
		fname);
	fflush(stdout);
    }
    else
    {
	fprintf(fp, "-11 0 0 0 0 %lu\n", (unsigned long) usc_rollover_val());
	for( logp = log_table ; logp < log_index ; logp++ )
	{
	    fprintf(fp, "%ld %ld %ld %ld %ld %lu\n",
		    (long) logp->event,
		    (long) _p_my_id,
		    (long) logp->task_id,
		    (long) logp->ii_data,
		    (long) logp->tind,
		    (unsigned long) logp->time);
	}
	fclose(fp);
	free(log_table);
	_p_upshot = FALSE;

	if (_p_host)
	{
	    fprintf(_p_stdout, "Done writing: %s.*\n", _p_upshot_file);
	    fflush(_p_stdout);
	}
    }
} /* write_log_c */

#endif /* UPSHOT */


/*
 * internal_log_event()
 *
 * This is the guts of the event logging.  All off the procedures
 * below are simply wrappers around this.
 *
 * It writes arguments into log table pointed to by 'log_index'.
 *
 * A warning is printed if the event table is full.
 *
 * The bit of mess with 'prev_time' and 'ind_slot' is because the micro-
 * second timer usually rolls at 2^32, which is a little over an hour.
 * If any event has a smaller time than the previous event, then the timer
 * must have rolled at some time between the two events.  If this happens,
 * then 'ind_time' is incremented to indicate the fact.  The logfiles
 * should be sorted together with 'ind_time' as the major field, and
 * 'time' as the minor field.
 *
 * NOTE: If the timer rolls *twice or more* between events, then the logs
 * will be totally screwed up.
 *
 */
static void internal_log_event(task_id, event, ii_data)
int_t *task_id;
int_t *event;
int_t *ii_data;
{
#ifdef UPSHOT    
    static usc_time_t prev_time = 0;
    static int_t ind_time = 0;
    static bool_t print_warning = TRUE;

    if (!_p_upshot)
	return;
    
    if ( log_index >= end_table )
    {
	if (print_warning)
	{
	    fprintf(_p_stdout,
		    "Warning: Upshot: Event buffer overflow (%ld events)\n",
		    (long) _p_upshot_log_size);
	    fflush(stdout);
	    print_warning = FALSE;
	}
    }
    else
    {
	log_index->task_id = *task_id;
	log_index->event = *event;
	log_index->ii_data = *ii_data;

	log_index->time = usc_clock();
	if (log_index->time < prev_time)
	    ind_time++;
	log_index->tind = ind_time;
	prev_time = log_index->time;
	
	log_index++;
    }
#endif /* UPSHOT */
} /* internal_log_event() */


/*************** LOG_EVENT *****************************/

/* Interface for logging events from C procedures */
void c_log_event(event)
int event;
{
    int_t i_task = 0;
    int_t i_event = (int_t) event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from PCN procedures */
void pcn_log_event(event)
int_t *event;
{
    int_t i_task = 0;
    int_t i_data_val = 0;
    internal_log_event(&i_task, event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void LOG_EVENT_(event)
int *event;
{
    int_t i_task = 0;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void LOG_EVENT(event)
int *event;
{
    int_t i_task = 0;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void log_event_(event)
int *event;
{
    int_t i_task = 0;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void log_event(event)
int *event;
{
    int_t i_task = 0;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}


/*************** LOG_TASK_EVENT ***********************/

/* Interface for logging events from C procedures */
void c_log_task_event(task, event)
int task;
int event;
{
    int_t i_task = (int_t) task;
    int_t i_event = (int_t) event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from PCN procedures */
void pcn_log_task_event(task, event)
int_t *task;
int_t *event;
{
    int_t i_data_val = 0;
    internal_log_event(task, event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void LOG_TASK_EVENT_(task, event)
int *task;
int *event;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void LOG_TASK_EVENT(task, event)
int *task;
int *event;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void log_task_event_(task, event)
int *task;
int *event;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from Fortran procedures */
void log_task_event(task, event)
int *task;
int *event;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = 0;
    internal_log_event(&i_task, &i_event, &i_data_val);
}


/*************** LOG_TASK_EVENT_DATA ******************/

/* Interface for logging events from C procedures */
void c_log_task_event_data(task, event, data_val)
int task;
int event;
int data_val;
{
    int_t i_task = (int_t) task;
    int_t i_event = (int_t) event;
    int_t i_data_val = (int_t) data_val;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

/* Interface for logging events from PCN procedures */
void pcn_log_task_event_data(task, event, data_val)
int_t *task;
int_t *event;
int_t *data_val;
{
    internal_log_event(task, event, data_val);
}

/* Interface for logging events from Fortran procedures */
void LOG_TASK_EVENT_DATA_(task, event, data_val)
int *task;
int *event;
int *data_val;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = (int_t) *data_val;
    internal_log_event(&i_task, &i_event, &i_data_val);
}


/* Interface for logging events from Fortran procedures */
void LOG_TASK_EVENT_DATA(task, event, data_val)
int *task;
int *event;
int *data_val;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = (int_t) *data_val;
    internal_log_event(&i_task, &i_event, &i_data_val);
}


/* Interface for logging events from Fortran procedures */
void log_task_event_data_(task, event, data_val)
int *task;
int *event;
int *data_val;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = (int_t) *data_val;
    internal_log_event(&i_task, &i_event, &i_data_val);
}


/* Interface for logging events from Fortran procedures */
void log_task_event_data(task, event, data_val)
int *task;
int *event;
int *data_val;
{
    int_t i_task = (int_t) *task;
    int_t i_event = (int_t) *event;
    int_t i_data_val = (int_t) *data_val;
    internal_log_event(&i_task, &i_event, &i_data_val);
}

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