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

This is defs.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.
 *
 * defs.h -- Typedefs, some constants, instruction and kernel codes
 */

#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <math.h>

#include "pcn_c_hdr.h"

#if defined(hp9k8) || defined(hp9k7) || defined(hp9k3)
#ifndef hpux
#define hpux
#endif
#endif

#if defined(sun3) || defined(sun4)
#ifndef sun_os
#define sun_os
#endif
#endif

#if defined(next040)
#ifndef next_os
#define next_os 
#endif
#endif

#ifdef next_os
#include <libc.h>
#endif

#ifdef DEFINE_GLOBALS
#define GLOBAL
#else
#define GLOBAL extern
#endif

#if defined(PDB) && !defined(DEBUG)
#define DEBUG 0
#endif

#if defined(PDB) && !defined(DYNAMIC_PAM_LOADING)
#define DYNAMIC_PAM_LOADING
#endif

#if defined(PDB) && defined(PCN_HOST) && !defined(PDB_HOST)
#define PDB_HOST
#endif

#ifdef DEBUG
#define DEFINE_INSTR_NAMES
#endif
#include "pcn_instr.h"

#ifdef DEBUG
#define DEFINE_PCN_TAG_NAMES
#endif
#include "pcn_structs.h"


/*
 * Argument parsing stuff.
 */

#define ARGTYPE_STRING 1
#define ARGTYPE_INTEGER 2
#define ARGTYPE_NONE 3
#define ARGTYPE_LIST 4

#define STRING_ARG(flag, value, usage) \
{ flag, ARGTYPE_STRING, (void *) value, 0, usage}

#define INTEGER_ARG(flag, value, usage) \
{ flag, ARGTYPE_INTEGER, (void *) value, 0, usage}

#define BOOL_ARG(flag, value, usage) \
{ flag, ARGTYPE_NONE, (void *) value, 0, usage}

#ifdef PCNCC
#define LIST_ARG(flag, value, usage) \
{ flag, ARGTYPE_LIST, (void *) value, 0, usage}
#endif /* PCNCC */

typedef struct _argdesc_t
{
    char *flag;
    int argtype;
    void *argval;
    void *default_value;
    char *usage;
} argdesc_t;

/*
 * General stuff
 */

#ifndef PARALLEL
#undef ASYNC_MSG
#define ASYNC_MSG	1
#endif /* PARALLEL */    

#ifdef DEBUG
#ifndef EM_DL
#define EM_DL DEBUG
#endif  /* EM_DL */
#ifndef GC_DL
#define GC_DL DEBUG
#endif  /* GC_DL */
#ifndef PAR_DL
#define PAR_DL DEBUG
#endif  /* PAR_DL */
#endif

#define PAM_VERSION_NUM 1		/* version # for module header */
#ifndef VERSION_STR
#define VERSION_STR "1.2"		/* version number (a string) */
#endif
#ifdef PDB
#define PDB_BANNER_STR " (PDB)"
#else
#define PDB_BANNER_STR ""
#endif

#include "pcn_structs.h"

/*
 * Some configuration parameters that can be overridded from the
 * command line during compilation.  If you want to override these,
 * add it to the PCN_DEFS in the Makefile or the configuration
 * file (in the Configs directory)
 */
#ifndef DEFAULT_NODES
		/* default number of nodes */
#define DEFAULT_NODES			1
#endif
#ifndef DEFAULT_HEAP_SIZE
		/* (in cells) size of heap */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_HEAP_SIZE		524288
#endif
#ifndef DEFAULT_HEAP_INC_PROXIMITY
		/* (in cells) if we get this close to top, increase */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_HEAP_INC_PROXIMITY	0
#endif
#ifndef INC_PROXIMITY_DIVISOR
		/* inc proximity divisor, if heap_inc_proximity==0 */
		/* See extern.h for detailed comments on heap management */
#define INC_PROXIMITY_DIVISOR		4
#endif
#ifndef DEFAULT_HEAP_INCREMENT
		/* (in cells) increment size when heap fills */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_HEAP_INCREMENT		0
#endif
#ifndef DEFAULT_HEAP_FREE_AFTER_GC
		/* (in cells) after gc, use this much before next gc */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_HEAP_FREE_AFTER_GC	0
#endif
#ifndef DEFAULT_HEAP_LOWAT
		/* (in cells) low water mark (shrink heap to this) */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_HEAP_LOWAT		0
#endif
#ifndef DEFAULT_HEAP_HIWAT
		/* (in cells) high water mark (never grow past this) */
		/* See extern.h for detailed comments on heap management */
#if CELL_SIZE == 4
#define DEFAULT_HEAP_HIWAT		2147483647
					/* 2^31-1 */
#else /* CELL_SIZE == 8 */
#define DEFAULT_HEAP_HIWAT		9223372036854775807
					/* 2^63-1 */
#endif
#endif
#ifndef DEFAULT_GC_SLACK
		/* (in cells) gc slack space at top of heap */
		/* See extern.h for detailed comments on heap management */
#define DEFAULT_GC_SLACK		0
#endif
#ifndef GC_SLACK_DIVISOR
		/* gc slack divisor, if gc_slack==0 */
		/* See extern.h for detailed comments on heap management */
#define GC_SLACK_DIVISOR		256
#endif
#ifndef DEFAULT_IRT_INITIAL_SIZE
		/* (in IRT entries) size of initial IRT */
		/* See extern.h for detailed comments on IRT management */
#define DEFAULT_IRT_INITIAL_SIZE	-10
#endif
#ifndef DEFAULT_IRT_INCREMENT
		/* (in IRT entries) gc slack space at top of heap */
		/* See extern.h for detailed comments on IRT management */
#define DEFAULT_IRT_INCREMENT		-10
#endif
#ifndef DEFAULT_GSQ_INTERVAL
		/* (# reductions) Global suspension queue reschedule interval*/
#define DEFAULT_GSQ_INTERVAL		1000
#endif
#ifndef PCN_TMP_DIR
		/* (string) directory for putting temporary files */
#define PCN_TMP_DIR			"/tmp"
#endif
#ifndef TIMESLICE
		/* Time slice (# tail recursions without context switch) */
#define TIMESLICE			50
#endif
#ifndef MSG_SKIP_POLL
		/* Skip msg poll this many timeslices (0 = none) */
#define MSG_SKIP_POLL			0
#endif
#ifndef PCN_PAGE_SIZE
		/* (in cells) Size of pages that are allocated
		 * for proc_records.
		 * This size need not relate to the hardware page
		 * size of a particular machine.
		 * This size must be >= ProcRecordSize(255)
		 */
#define PCN_PAGE_SIZE			2048
#endif
#ifndef INIT_WEIGHT
		/* Initial weight for remote references */
#define INIT_WEIGHT			1000000
#endif
#ifndef CT_STACK_SIZE
		/* stack size for copy_term() -- if you passing BIG
		 * tuples between nodes, you might want to increase this
		 */
#define CT_STACK_SIZE			1024
#endif
#ifndef CANCEL_SIZE
		/* (in cells) size of cancel messages */
#define CANCEL_SIZE			256
#endif

#ifndef PRINT_ARRAY_SIZE_DEFAULT
		/* default array size to print in print_term() */
#define PRINT_ARRAY_SIZE_DEFAULT	5
#endif
#ifndef PRINT_TUPLE_DEPTH_DEFAULT
		/* default tuple depth to print in _p_print_term() */
#define PRINT_TUPLE_DEPTH_DEFAULT	100
#endif
#ifndef PRINT_TUPLE_WIDTH_DEFAULT
		/* default tuple width to print in _p_print_term() */
#define PRINT_TUPLE_WIDTH_DEFAULT	10
#endif

#ifndef MAX_SYMBOL_LENGTH
		/* max length of any symbol name (i.e., procedure name, etc) */
#define MAX_SYMBOL_LENGTH		1024
#endif
#ifndef MAX_PATH_LENGTH
		/* max length of any file path */
#define MAX_PATH_LENGTH			1024
#endif


/*
 * The following should not be changed
 */
#define GC_REF_STACK_SIZE		270
#define NUM_A_REGS			256
#define NUM_F_REGS			64
#define DEFAULT_FIRST_UNUSED_REGISTER	256


#if CELL_BITS == 32

/* With 32 bit cells, max queue size is 2^31-1 */
#define MAX_PROC_QUEUE_SIZE 2147483647

#define MAX_IRT_TABLE_SIZE  2147483646
#define RREF_NOT_READ_IRT   2147483647

#else

/* With 64 bit cells, max queue size is 2^63-1 */
#define MAX_PROC_QUEUE_SIZE 9223372036854775807

#define MAX_IRT_TABLE_SIZE 9223372036854775806
#define RREF_NOT_READ_IRT  9223372036854775807

#endif


/*
 * proc_record_t
 *
 * Process record.
 *
 * The 'header' has a tag of PROC_RECORD_TAG, and the header->size
 * field contains the maximum number of arguments this proc_record
 * can hold.
 *
 * WARNING:  There is a special relationship between the proc_record_t
 * and the value_note_t.  Since they both appear on suspension queues,
 * and since it would be a nuisance to have to deal with them
 * differently when doing routine queue maintainence, it is assumed
 * that the 'next' field is in the same location (relative to the
 * header) in the proc_record_t and the value_note_t.
 */
typedef struct proc_record_struct {
    data_header_t		header;
    struct proc_record_struct *	next;
    proc_header_t *		proc;
#ifdef PDB
    u_int_t			instance;
    u_int_t			reduction;
    proc_header_t *		called_by;
    struct proc_record_struct *	pdb_prev;
    struct proc_record_struct *	pdb_next;
#endif /* PDB */
    cell_t *			args[1];
} proc_record_t;
#define ProcRecordBaseSize	(sizeof(proc_record_t) / CELL_SIZE) - 1
#define ProcRecordSize(N)	(ProcRecordBaseSize + N)
    
/*
 * value_note_t
 *
 * A value note is a marker on an undefined variable's (or
 * remote reference's) suspension queue which keeps track
 * of the fact that another node has requested the data for
 * this undefined variable.  When the data becomes available,
 * the information in the value note will be used to generate
 * a reply message.
 *
 * The weight associated with a value note is assumed to be 1.
 *
 * WARNING:  There is a special relationship between the proc_record_t
 * and the value_note_t.  See the comment above for proc_record_t...
 */
typedef struct value_note_struct {
    data_header_t		header;
    struct value_note_struct *	next;
    u_int_t			node;
    u_int_t			location;
} value_note_t;
#define ValueNoteSize	(sizeof(value_note_t) / CELL_SIZE)


/*
 * irt_t
 *
 * Typedef for Incoming Reference Table (IRT) entries.
 *
 * If 'weight' is 0, then this entry is not used, and 'next_free'
 * contains the irt index of the next free entry, or -1 if there are no
 * more unused irt entries.  This is used, instead of the old pointer
 * based free list, so that we can avoid having to map back from address
 * to index number.
 *
 * If 'weight' is > 0, then this entry is used and 'ptr' pointer points
 * to the data on the heap for this entry.
 */
typedef struct irt_struct
{
    u_int_t weight;
    union
    {
	int_t  next_free;
	cell_t *ptr;
    } u;
} irt_t;
#define IrtEntrySize	(sizeof(irt_t) / CELL_SIZE)


/*
 * rref_t
 *
 * Typedef for a remote reference.  The fields are:
 *	tag	  : RREF_TAG \__ These field should be in same spot as
 *				 in the data_header_t
 *	mark	  : mark bit /
 *	suspensions: If 1, there are suspensions.  This field should be in the
 *			same spot as in undef_t
 *	high_part_ptr: Part of pointer to suspension queue.
 *	node      : The node on which the data for this remote reference lives
 *	location  : IRT index on the remote node for this remote reference
 *	weight    : Weight.  Maximum weight is 2^(CELL_BITS-TAG_SIZE),
 *			due to the ct_rref_t structure packing
 *	value_return_irt: When we send off a MSG_READ request to
 *			another node for this rref, then stow away
 *			the IRT entry on my node that will be used
 *			for the returning MSG_VALUE message.
 *			This will be sent along with the MSG_DEFINE
 *			message if I subsequently define a value to
 *			this rref.  The receiving node of the define
 *			message can then use this to determine if it
 *			needs to return a MSG_VALUE message.
 *			If this field is set to RREF_NOT_READ_IRT, then
 *			no MSG_READ request has been sent for this rref.
 *	low_part_ptr: Rest of pointer to suspension queue.
 *	trailer_tag: RREF_TRAILER_TAG
 *
 * Note: _p_define() (in utils.c) and _p_send_cancels() (in parallel.c)
 * exploit the order of the field in this rref_t structure.  In particular,
 * it counts on 'node', 'location', and 'weight'
 * being the second, third, and fourth words
 * of this structure, respectively.  Sure its a hack.
 * But when a rref is defined due to a value message being
 * received, it allows irt cancel information to be
 * queued up quickly so that cancel messages
 * can be sent for them later.  If you change this structure, make
 * sure that you update _p_define() and _p_send_cancels().
 */
typedef struct {
#ifdef PCN_BIT_FIELDS_R_TO_L
    u_int_t	tag		: TAG_SIZE;
    u_int_t	mark		: 1;
    u_int_t	suspensions	: 1;
    u_int_t	high_part_ptr	: (CELL_BITS - TAG_SIZE - 2);
#else  /* PCN_BIT_FIELDS_R_TO_L */
    u_int_t	high_part_ptr	: (CELL_BITS - TAG_SIZE - 2);
    u_int_t	suspensions	: 1;
    u_int_t	mark		: 1;
    u_int_t	tag		: TAG_SIZE;
#endif /* PCN_BIT_FIELDS_R_TO_L */
    u_int_t		node;
    u_int_t		location;
    u_int_t		weight;
    u_int_t		value_return_irt;
#ifdef PCN_BIT_FIELDS_R_TO_L
    u_int_t	trailer_tag	: TAG_SIZE;
    u_int_t	low_part_ptr	: (CELL_BITS - TAG_SIZE);
#else  /* PCN_BIT_FIELDS_R_TO_L */
    u_int_t	low_part_ptr	: (CELL_BITS - TAG_SIZE);
    u_int_t	trailer_tag	: TAG_SIZE;
#endif /* PCN_BIT_FIELDS_R_TO_L */
} rref_t;
#define RrefSize	(sizeof(rref_t) / CELL_SIZE)


/*
 * undef_t
 *
 * Typedef for an undefined variable.  The fields are
 *	tag	  : RREF_TAG \__ These field should be in same spot as
 *				 in the data_header_t
 *	mark	  : mark bit /
 *	suspensions: If 1, there are suspensions.  This field should be in the
 *			same spot as in undef_t
 *	high_part_ptr: Part of pointer to suspension queue.
 *	low_part_ptr: Rest of pointer to suspension queue.
 *	trailer_tag: RREF_TRAILER_TAG
 */
typedef struct {
#ifdef PCN_BIT_FIELDS_R_TO_L
    u_int_t	tag		: TAG_SIZE;
    u_int_t	mark		: 1;
    u_int_t	suspensions	: 1;
    u_int_t	high_part_ptr	: (CELL_BITS - TAG_SIZE - 2);
#else  /* PCN_BIT_FIELDS_R_TO_L */
    u_int_t	high_part_ptr	: (CELL_BITS - TAG_SIZE - 2);
    u_int_t	suspensions	: 1;
    u_int_t	mark		: 1;
    u_int_t	tag		: TAG_SIZE;
#endif /* PCN_BIT_FIELDS_R_TO_L */
#ifdef PCN_BIT_FIELDS_R_TO_L
    u_int_t	trailer_tag	: TAG_SIZE;
    u_int_t	low_part_ptr	: (CELL_BITS - TAG_SIZE);
#else  /* PCN_BIT_FIELDS_R_TO_L */
    u_int_t	low_part_ptr	: (CELL_BITS - TAG_SIZE);
    u_int_t	trailer_tag	: TAG_SIZE;
#endif /* PCN_BIT_FIELDS_R_TO_L */
} undef_t;
#define UndefSize	(sizeof(undef_t) / CELL_SIZE)


/*
 * list_t
 *
 * This is a generic linked list type.
 */
typedef struct list_struct {
    struct list_struct *	next;
    void *			value;
} list_t;


#ifdef STREAMS

typedef struct local_stream_msg_struct {
    struct local_stream_msg_struct *next;
    u_int_t	tag;
    u_int_t	offset;
    u_int_t	size;
    cell_t	data[1];
} local_stream_msg_t;
#define LocalStreamMsgBaseSize	((sizeof(local_stream_msg_t) / CELL_SIZE) - 1)

/*
 * stream_t
 *
 * On the heap, an array (of size n) of streams is a data_header_t
 * with tag=STREAM_TAG, followed by n stream_t data structures.
 *
 * The fields have the following meanings:
 *   send	: 1 if this is the send side of the stream, 0 if it is
 *			the receive side
 *   remote	: 1 if this is a remote stream, 0 if it a local stream
 *   state	: marks if there is a pending send or receive on this
 *			stream:
 *				0 means no pending send or receive.
 *				1 means there was a local send before
 *					a recv was posted (use lq.* struct)
 *				2 means there was a recv before a send
 *					was posted (use r.* struct)
 *   open	: 1 if this stream is still open, 0 if it has been closed
 *   pad	: reserved space to fill out the first cell
 *   id		: the stream id
 *   r.array	: pointer to held array on heap. (state==2)
 *   r.offset	: offset into held array
 *   r.size	: size of held array to work with
 *   r.status	: pointer to undefined status variable (when a recv is
 *			posted before a send)
 *   lq.head	: local stream message queue -- head of queue (state==1)
 *   lq.tail	: local stream message queue -- tail of queue
 *   s.node	: the node on which the receiving side of the stream lives
 */
typedef struct {
    u_int_t	send		: 1;
    u_int_t	remote		: 1;
    u_int_t	state		: 2;
    u_int_t	open		: 1;
    u_int_t	pad		: (CELL_BITS - 5);
    int_t	id;
    union {
	struct {		/* Receive side */
	    cell_t *	array;
	    u_int_t	offset;
	    u_int_t	size;
	    cell_t *	status;
	} r;
	struct {		/* Local stream message queue (receive side) */
	    local_stream_msg_t *queue_head;
	    local_stream_msg_t *queue_tail;
	} lq;
	struct {		/* Send side */
	    u_int_t	node;
	} s;
    } u;
} stream_t;
#define StreamEntrySize	(sizeof(stream_t) / CELL_SIZE)

#endif /* STREAMS */


/*
 * Argument types for _p_process_messages()
 */
#define RCV_NOBLOCK		0
#define RCV_BLOCK		1
#define RCV_PARAMS		2
#define	RCV_COLLECT		3
#define	RCV_GAUGE		4

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