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.