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

This is extern.h 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.
 *
 * extern.h  -  definition of global variables
 *
 *   In case you are wondering about all these '_p_' prefixes to global
 * variables and functions, that was done to avoid naming conflicts with
 * foreign object files that might be linked in.  All global variables
 * and functions begin with '_p_', except for the pcn "registers" which
 * are all upper case letters.  Its a bit of a pain in the butt, but it
 * does the trick.
 */

GLOBAL	int	errno;

/*
 * Heap related variables.
 *
 * The heap is layed out as follows:
 *   The heap consists of a certain number of cells, _p_heap_size.  This
 *   space is divided into several sections, from the top down:
 *    - Pages for process records go at the top of the heap.
 *	On a machine that support virtual memory, this region can be
 *	empty, since these pages can be malloc()'ed.  This is specified
 *	by the NO_VIRTUAL_MEMORY.
 *    - A small buffer region, to guarantee that MSG_CANCEL messages have
 *	enough room on the heap.  This is only used in multiprocessor runs.
 *	This region has CANCEL_SIZE cells in it.
 *    - The gc slack region.  If the heap grows to within this region,
 *	the garbage collector will be invoked between reductions.
 *    - The primary, data structure region.  This is where all the data goes.
 *
 * The various _p_heap_* variables designate the heap parameters, such
 * as size, boundaries between the regions, etc.  All of the
 * _p_heap_*_top variables are the cell AFTER the last valid cell
 * in that region.  All of the _p_heap_* variables refer to a size cells.
 *
 *   _p_heap_real_top
 *		Last cell of entire heap, including the pages region.
 *   _p_heap_cancel_top
 *		Last cell the cancel buffer region.
 *   _p_heap_hard_top
 *		Last cell of the gc slack region.  The is absolute
 *		top cell that can be used by normal data allocation routines.
 *   _p_heap_gc_top
 *		Last cell of primary region, just before gc slack region.
 *   _p_heap_bottom
 *		First cell of the primary region.
 *   _p_heap_ptr
 *		Next unused cell in the heap
 *   _p_heap_size
 *		Size of the heap
 *   _p_heap_inc_proximity
 *		If the heap becomes within _p_heap_inc_proximity of
 *		full after a gc, then increase the heap.
 *		If set to 0, then use:
 *			(_p_heap_size / INC_PROXIMITY_DIVISOR) + 1
 *   _p_heap_increment
 *		Increase the heap by this much if it fills up.
 *		If set to 0, then use the initial _p_heap_size for
 *		this parameter.
 *   _p_heap_free_after_gc
 *		After a garbage collection, if there is more than this
 *		amount free, then use this amount of heap before
 *		collecting again.
 *		If set to 0, then always use all free space.
 *   _p_heap_lowat
 *		Low water mark.  This is the minimum size of that the
 *		heap will be shrunk to, regardless of _p_heap_free_after_gc.
 *   _p_heap_hiwat
 *		High water mark.  The heap must never grow to be greater
 *		than this size.
 *   _p_gc_slack
 *		In the absence of the _p_heap_free_after_gc and the
 *		_p_heap_lowat values coming into play, use this as
 *		the gc slack.  (If we get within this proximity of the
 *		top of the heap between reductions, then gc.)
 *		If set to 0, then use:
 *			(_p_heap_size / GC_SLACK_DIVISOR) + 1
 *
 * From the _p_heap_cancel_top, you can calculate the _p_heap_hard_top
 * and _p_heap_gc_top.
 *
 * As these variables indicate, the heap can grow and shrink over the
 * course of the run.  Ideally, you want to make sure the low water
 * mark is below the working set of real memory on a particular machine,
 * so that unless the heap usage grows significantly it will run
 * without paging.
 */
GLOBAL	cell_t *_p_heap_real_top;
GLOBAL	cell_t *_p_heap_cancel_top;
GLOBAL	cell_t *_p_heap_hard_top;
GLOBAL  cell_t *_p_heap_gc_top;
GLOBAL	cell_t *_p_heap_bottom;
GLOBAL  cell_t *_p_heap_ptr;
GLOBAL	int_t	_p_heap_size;
GLOBAL	int_t	_p_heap_inc_proximity;
GLOBAL	int_t	_p_heap_increment;
GLOBAL	int_t	_p_heap_free_after_gc;
GLOBAL	int_t	_p_heap_lowat;
GLOBAL	int_t	_p_heap_hiwat;
GLOBAL	int_t	_p_gc_slack;
#ifdef PCN_ALIGN_DOUBLES
GLOBAL	int_t	_p_heap_bottom_pad;
#endif

/*
 * IRT related variables
 *
 * On a parallel system, the IRT (Incoming Reference Table) holds
 * references into the heap from remote references on other nodes.
 * The remote reference contains an IRT index which remains constant
 * through garbage collection, allowing nodes to gc asynchronously
 * with respect to other nodes.
 *
 * The IRT related variables are:
 *   _p_irt_initial_size
 *		The initial size of the IRT.  If >0, then it is the
 *		number of entries.  If <0, it means the initial
 *		size should be the number of nodes in this parallel
 *		run multiplied by the absolute value of this variable.
 *   _p_irt_increment
 *		When the IRT fills up, increment the size of the
 *		IRT by this much.  Negative values are interpreted
 *		like _p_irt_initial_size.
 *   _p_irt_size
 *		The current size of the IRT, in entries.
 *   _p_irt
 *		Pointer to the first entry in the IRT table.
 *   _p_irt_free_list
 *		Index of the first free entry in the table.
 *
 * On a machine with virtual memory, the IRT can grow arbitrarily
 * in size by using realloc().  On machines without
 * virtual memory, the IRT is fixed in size to
 * the _p_irt_initial_size.  If we run out of entries,
 * then we abort the run with a fatal error message.
 */
GLOBAL	int_t	_p_irt_initial_size;
GLOBAL	int_t	_p_irt_increment;
GLOBAL	int_t	_p_irt_size;
GLOBAL	irt_t *	_p_irt;
GLOBAL	int_t	_p_irt_free_list;


/*
 * This is array that will be malloced to a size of _p_nodes.  It
 * is used to keep track of the cancel messages that need to be
 * sent to each node from this one.
 *
 * It is used in two ways:
 *   1) During normal emulation, entries may be on the cancel lists
 *	in one of two ways:
 *	     a) In utils.c:process_susp_queue(), if we find that we do not
 *		need to generate a value message for a particular value
 *		note because the term originally came from the node/irt
 *		pointed to by the value node, then put the value note
 *		onto the linked list pointed to by _p_cancel_lists[the_node].
 *	     b) In _p_define(), if we are defining to a rref with
 *		a term that came from a value message, then we do not
 *		need to generate a define message for this rref
 *		but instead need to cancel the irt associated with
 *		this irt.  So in this case, the first word of the rref
 *		is overwritten with a pointer to the term, and the
 *		remaining words of the rref are put onto the linked
 *		list pointed to by _p_cancel_lists[the_node].  
 *	Cancellations to be sent out for these two things
 *	at the beginning of the next garbage collection.
 *   2) During a garbage collection, if an orphaned rref
 *      or value note is found during the gc, it is put on
 *      the linked list pointed to by _p_cancel_lists[the_node].
 *      Between gc scans, _p_send_cancels() will be called to
 *      send out the appropriate cancel messages.
 */
GLOBAL	cell_t **	_p_cancel_lists;
GLOBAL	int_t		_p_cancels;


/*
 * Various emulator state variables...
 */
GLOBAL	proc_record_t *_p_active_qf;	/* active queue front */
GLOBAL	proc_record_t *_p_active_qb;	/* active queue back */
GLOBAL	proc_record_t *_p_globsusp_qf;	/* global suspension queue front */
GLOBAL	proc_record_t *_p_globsusp_qb;	/* global suspension queue back */
GLOBAL	proc_record_t *_p_current_proc;	/* current process */
GLOBAL	cell_t *_p_structure_ptr;	/* structure pointer */
GLOBAL	cell_t *_p_structure_start_ptr;	/* structure start pointer */
GLOBAL	cell_t *_p_suspension_var;	/* variable from last suspension */
GLOBAL	cell_t *_p_a_reg[NUM_A_REGS];	/* Argument and temporary registers */
GLOBAL	void *	_p_f_reg[NUM_F_REGS];	/* Foreign proc argument registers */
GLOBAL	void **	_p_foreign_ptr;		/* Foreign proc argument pointer */

GLOBAL	cell_t **_p_gc_ref_stack[GC_REF_STACK_SIZE]; /* gc reference stack */
GLOBAL	int_t	_p_gc_ref_stack_top;
GLOBAL	int_t	_p_first_unused_register; /* Normally 256 -- used by gc */

GLOBAL	u_int_t	_p_my_id;	/* node id */
GLOBAL	u_int_t	_p_host_id;	/* host id */
GLOBAL	u_int_t	_p_nodes;	/* number of nodes */
GLOBAL	bool_t	_p_multiprocessing;	/* Are we multiprocessing? */
GLOBAL	bool_t	_p_host;		/* Am I the host node? */

GLOBAL	u_int_t _p_reduction;	/* Counter of what reduction we're on */
GLOBAL	u_int_t	_p_gsq_interval;/* Interval (in reductions) between global */
				/*   suspension queue reschedules	   */
GLOBAL	u_int_t	_p_vt_debug_level;/* VT debug level to pass in boot argument */
GLOBAL	bool_t	_p_no_signal_handlers;

GLOBAL  FILE 	*_p_stdout;
GLOBAL	bool_t	_p_use_logfile;

GLOBAL	char	_p_boot_mod[MAX_SYMBOL_LENGTH];	/* boot module and procedure */
GLOBAL	char	_p_boot_proc[MAX_SYMBOL_LENGTH];
GLOBAL	char	_p_main_mod[MAX_SYMBOL_LENGTH];	/* main module and procedure */
GLOBAL	char	_p_main_proc[MAX_SYMBOL_LENGTH];

#ifdef PARALLEL
GLOBAL	int_t	_p_default_msg_buffer_size;
#endif /* PARALLEL */

#ifdef PARALLEL
#if ASYNC_MSG == 1
GLOBAL	bool_t	_p_msg_avail;
#else
GLOBAL	int	_p_msg_skip;
#endif /* ASYNC_MSG */
#endif /* PARALLEL */

#ifdef PDB
GLOBAL	proc_record_t *_pdb_all_qf;	/* Complete PDB process list front */
GLOBAL	proc_record_t *_pdb_all_qb;	/* Complete PDB process list back */
GLOBAL	proc_record_t *_pdb_pending_qf;	/* PDB pending queue front */
GLOBAL	proc_record_t *_pdb_pending_qb;	/* PDB pending queue back */
GLOBAL	bool_t	_pdb_breakout;		/* Flag to break out to debugger */
GLOBAL	u_int_t	_pdb_reduction_break;	/* Next reduction at which to break */
GLOBAL	bool_t	_pdb_empty_queue_break; /* Break to PDB if queues are empty? */
GLOBAL	bool_t	_pdb_print_orphaned;	/* Print orphaned procs during GC */
GLOBAL	bool_t	_pdb_enter_immediately; /*Enter PDB immediately upon startup?*/
GLOBAL	bool_t	_pdb_gc_after_foreign;  /* Do a GC after each foreign call? */
GLOBAL	u_int_t	_pdb_last_called_foreign;/* The last foreign called */
#endif /* PDB */

#define INITIAL_LOAD_PAM_FILES_LENGTH 1024
#ifdef DYNAMIC_PAM_LOADING    
GLOBAL	char_t	_p_initial_load_pam_files[INITIAL_LOAD_PAM_FILES_LENGTH];
					/* Pams to load initially */
#endif /* DYNAMIC_PAM_LOADING */

#ifdef DEFINE_GLOBALS
char	*_p_arch_string = PCN_ARCH;
#else
extern	char	*_p_arch_string;
#endif


#ifdef GAUGE
GLOBAL bool_t	_p_gauge;	/* Gauge enabled for this run? */
GLOBAL char_t	_p_gauge_file[MAX_PATH_LENGTH];	/* Gauge output file */
GLOBAL char_t	_p_gauge_tmp_file[MAX_PATH_LENGTH];
GLOBAL char_t	_p_tmp_dir[MAX_PATH_LENGTH];	/* Directory for tmp files */
#endif /* GAUGE */

#ifdef UPSHOT
GLOBAL bool_t	_p_upshot;	/* Upshot enabled for this run? */
GLOBAL char_t	_p_upshot_file[MAX_PATH_LENGTH]; /* Upshot output file */
GLOBAL int_t	_p_upshot_log_size;	/* Size of Upshot log buffer */
#endif /* UPSHOT */


/*
 * These are defined in the custom info file that is generated by pcnlink.
 *
 * The _p_exported_table has (_p_exported_table_size+1) entries.
 * The first _p_exported_table_size entries are the hash table of
 * exported proc_headers.  The last entry is a pointer to the
 * list of non-exported procedures.  This was done to make it
 * easier to iterate through all of the proc_headers in PDB and Gauge,
 * without special casing non-exported procedures.
 */
extern	char_t	*_p_user_banner;
extern	char_t	*_p_d_boot_mod;
extern	char_t	*_p_d_boot_proc;
extern	char_t	*_p_d_main_mod;
extern	char_t	*_p_d_main_proc;
extern	int_t	_p_d_nodes;
extern	int_t	_p_d_heap_size;
extern	int_t	_p_d_heap_inc_proximity;
extern	int_t	_p_d_heap_increment;
extern	int_t	_p_d_heap_free_after_gc;
extern	int_t	_p_d_heap_lowat;
extern	int_t	_p_d_heap_hiwat;
extern	int_t	_p_d_gc_slack;
extern	int_t	_p_d_irt_initial_size;
extern	int_t	_p_d_irt_increment;
extern	int_t	_p_d_gsq_interval;
extern	int_t			_p_exported_table_size;
extern	proc_header_t *		_p_exported_table[];	/* See comment above */
#ifdef DEBUG
extern	int_t			_p_foreign_table_size;
extern	foreign_table_t		_p_foreign_table[];
#endif /* DEBUG */
#ifdef PDB
extern	int_t	_p_compiled_with_pdb;
#else
extern	int_t	_p_not_compiled_with_pdb;
#endif
#ifdef PCN_PROFILE
extern	int_t _p_compiled_with_profile;
#else
extern	int_t _p_not_compiled_with_profile;
#endif


GLOBAL	int	_p_print_array_size;	/* Used to control _p_print_term() */
GLOBAL	int	_p_print_tuple_depth;	/* Used to control _p_print_term() */
GLOBAL	int	_p_print_tuple_width;	/* Used to control _p_print_term() */


/*
 * And some debugging stuff
 */
#ifdef DEBUG

GLOBAL	int_t	_p_global_dl;	/* global debug level */
GLOBAL	int_t	_p_em_dl;	/* emulator debug level */
GLOBAL	int_t	_p_gc_dl;	/* garbage collector debug level */
GLOBAL	int_t	_p_par_dl;	/* parallel code debug level */
GLOBAL	int_t	_p_start_em_debug;  /* start em debug after n reductions */
#if defined(PARALLEL) && defined(PCN_HOST)
GLOBAL	int_t	_p_n_global_dl;	/* global debug level on nodes */
GLOBAL	int_t	_p_n_em_dl;	/* emulator debug level on nodes */
GLOBAL	int_t	_p_n_gc_dl;	/* garbage collector debug level on nodes */
GLOBAL	int_t	_p_n_par_dl;	/* parallel code debug level on nodes */
GLOBAL	int_t	_p_n_start_em_debug;  /* start em debug after n reductions */
GLOBAL	int_t	_p_debug_node;	/* the node to run debug levels on */
#endif /* PARALLEL && PCN_HOST */

#endif /* DEBUG */


/*
 * Here are all of the external (global) functions.
 */
/********** args.c	**********/
extern	int		_p_read_args();
/********** boot.c	**********/
extern	int		_p_pcn_main();
extern	void		_p_init_node();
extern	void		_p_shutdown_pcn();
extern	void		_p_fatal_error();
extern	void		_p_malloc_error();
/********** debug.c	**********/
extern	void		_p_print_term();
#ifdef DEBUG
extern	void		_p_print_proc_record();
extern	void		_p_print_proc();
extern	void		_p_print_program();
extern	void		_p_print_instruction();
#endif /* DEBUG */
/********** emulate.c	**********/
extern	void		_p_emulate();
/********** gauge.c	**********/
#ifdef GAUGE
extern	void		_p_init_gauge_tmp_file();
extern	void		_p_init_gauge();
extern	void		profile_reset();
extern	void		profile_snapshot();
extern	void		_p_process_gauge_msg();
#endif /* GAUGE */
/********** gc.c	**********/
extern	void		_p_collect_garbage();
/********** grow_heap.c	**********/
#ifndef NO_VIRTUAL_MEMORY
extern	void		_p_grow_heap();
#endif /* !NO_VIRTUAL_MEMORY */
/********** irt.c	**********/
extern	void		_p_init_irt();
extern	int_t		_p_alloc_irt_entry();
extern	void		_p_cancel_irt_entry();
/********** load_file.c	**********/
#ifdef DYNAMIC_PAM_LOADING    
extern	void		_p_load_pam_file_init();
extern	char_t *	_p_load_pam_file();
#endif /* DYNAMIC_PAM_LOADING */
/********** parallel.c	**********/
extern	void		_p_process_messages();
extern	void		_p_send_define();
extern	void		_p_send_value();
extern	void		_p_send_read();
extern	void		_p_send_cancels();
extern	void		_p_send_collect();
extern	void		_p_host_handle_exit();
extern	void		_p_node_handle_exit();
/********** pdb.c	**********/
#ifdef PDB
#ifdef PDB_HOST
extern	void		_pdb_init();
extern	void		_pdb_enter();
extern	bool_t		_pdb_query_to_abort();
#endif /* PDB_HOST */
extern	void		_pdb_orphaned_proc_record();
extern	void		_pdb_orphaned_value_note();
extern	u_int_t		_pdb_get_next_instance();
extern	void		_pdb_next_instance();
extern	void		_pdb_enqueue_process();
extern	void		_pdb_dequeue_process();
extern	void		_pdb_print_all_processes();
#endif /* PDB */
/********** procs.c	**********/
extern	void		_p_init_proc_record_pool();
extern	proc_record_t *	_p_alloc_proc_record();
extern	void		_p_free_proc_record();
extern	value_note_t *	_p_alloc_value_note();
extern	void		_p_free_value_note();
/********** upshot.c	**********/
extern	void		_p_init_upshot();
extern	void		_p_write_upshot_log();
/********** utils.c	**********/
extern	void		_p_do_exit();
extern	u_int_t		_p_size_without_trailer();
extern	u_int_t		_p_size_with_trailer();
extern	void		_p_em_hash_index_for_procedure_name();
extern	void		_p_hash_string();
extern	proc_header_t *	_p_proc_lookup();
extern	bool_t		_p_define();
extern	void		_p_bad_define();
extern	void		_p_print_banner();
#ifdef PCN_RENAME_TO_LINK
extern	int		_p_rename_to_link();
#endif /* PCN_RENAME_TO_LINK */
#ifdef DEBUG
extern	char *		_p_foreign_lookup();
#endif /* DEBUG */
/********** md_*.c	**********/
extern	void		_p_init_machine_dep();
extern	void		_p_shutdown_machine_dep();
extern	void		_p_abort_machine_dep();
#ifdef PDB
extern	char *		_p_fgets();
#endif /* PDB */
/********** sr_*.c	**********/
extern	void		_p_sr_get_argdesc();
extern	void		_p_sr_init_node();
extern	void		_p_sr_node_initialized();
extern	void		_p_destroy_nodes();
extern	void		_p_abort_nodes();
extern	cell_t *	_p_alloc_msg_buffer();
extern	void		_p_msg_send();
extern	bool_t		_p_msg_receive();
#ifdef STREAMS
extern	bool_t		_p_alloc_stream();
extern	void		_p_free_stream();
extern	void		_p_update_stream();
extern	stream_t *	_p_lookup_stream();
extern	cell_t *	_p_lookup_stream_header();
extern	int_t		_p_lookup_stream_index();
extern	bool_t		_p_first_stream();
extern	bool_t		_p_next_stream();
extern	void		_p_enable_stream_recv();
extern	void		_p_disable_stream_recv();
extern	void		_p_send_close_stream();
extern	void		_p_stream_send();
#endif /* STREAMS */
/********** streams.c	**********/
#ifdef STREAMS
extern	stream_t *	_p_get_stream_record();
extern	void		_p_close_stream();
extern	void		_p_enqueue_local_stream_msg();
extern	local_stream_msg_t *_p_dequeue_local_stream_msg();
extern	void		_p_free_local_stream_msg();
extern	void		_p_set_stream_recv_status();
#endif /* STREAMS */

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