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.