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 Netfuture.ch.