/*
 *           PVM 3.2:  Parallel Virtual Machine System 3.2
 *               University of Tennessee, Knoxville TN.
 *           Oak Ridge National Laboratory, Oak Ridge TN.
 *                   Emory University, Atlanta GA.
 *      Authors:  A. L. Beguelin, J. J. Dongarra, G. A. Geist,
 *    W. C. Jiang, R. J. Manchek, B. K. Moore, and V. S. Sunderam
 *                   (C) 1992 All Rights Reserved
 *
 *                              NOTICE
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted
 * provided that the above copyright notice appear in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * Neither the Institutions (Emory University, Oak Ridge National
 * Laboratory, and University of Tennessee) nor the Authors make any
 * representations about the suitability of this software for any
 * purpose.  This software is provided ``as is'' without express or
 * implied warranty.
 *
 * PVM 3.2 was funded in part by the U.S. Department of Energy, the
 * National Science Foundation and the State of Tennessee.
 */

/*
 *  pvmmimd.h
 *
$Log: pvmmimd.h,v $
 * Revision 1.1  1993/08/30  23:26:51  manchek
 * Initial revision
 *
 */

/* iPSC/860 */

#ifdef IMA_I860
#define CUBENAMELEN		16		/* max number of characters in cube name */
#define MAKECUBENAME(name,no)	(sprintf((name),"pvm%d",(no)))
#endif


/*
 * message handling routines
 *
 * ASYNCWAIT():		waits for asynchronous send/recv to complete
 * ASYNCDONE():		returns 1 if the asynchronous send/recv has completed; 0
 *					otherwise
 * ASYNCSEND():		asynchronous send
 * ASYNCRECV():		asynchronous receive
 * MSGSIZE():		length (in bytes) of pending/received message
 * MSGSENDER():		address of the sender
 */

#ifdef IMA_CM5

#include <cm/cmmd.h>
#define ASYNCDONE(mid)	CMMD_msg_done(mid)
#define ASYNCWAIT(mid)	CMMD_msg_wait(mid)
#define MSGSIZE(mid)	CMMD_mcb_bytes(mid)
#define MSGSENDER(mid)	CMMD_mcb_source(mid)
#define ASYNCRECV(buf,len)	\
	CMMD_receive_async(CMMD_ANY_NODE,CMMD_ANY_TAG,buf,len,(void*)0,(void*)0)
#define ASYNCSEND(tag,buf,len,dest,ptype)	\
	CMMD_send_async((int)(dest),tag,buf,len,(void*)0,(void*)0)
#define PVMCSEND(tag,buf,len,dest,ptype)	\
	CMMD_send_noblock((int)(dest),tag,buf,len)
#define NUMSMIDS	90			/* the CM5 has about 100 message IDs */

#endif /*IMA_CM5*/

#if defined(IMA_PGON) || defined(IMA_I860)

#define ASYNCDONE(mid)	_msgdone(mid)
#define ASYNCWAIT(mid)	_msgwait(mid)
#define MSGSIZE(mid)	_infocount()
#define MSGSENDER(mid)	_infonode()
#define ASYNCRECV(buf,len)					_irecv((long)recvmask,buf,(long)len)
#define ASYNCSEND(tag,buf,len,dest,ptype)	_isend(tag,buf,(long)len,dest,ptype)
#define PVMCSEND(tag,buf,len,dest,ptype)	_csend(tag,buf,(long)len,dest,ptype)
#define NUMSMIDS	64			/* the Paragon has 999 message IDs (snd/recv) */
								/* msg buffer for Paragon holds 1MB; = 64x16K */

#endif /*IMA_PGON/IMA_I860*/


/* nodes in use */

struct nodeset {
	struct nodeset *n_link;		/* linked list */
	struct nodeset *n_rlink;
	int n_size;					/* number of nodes */
	int n_first;				/* the first node in the set */
	int n_ptype;				/* (PGON) ptype of tasks on the nodes  */
	int n_alive;				/* number of active nodes */
	int n_ptid;					/* tid of task who spawned us */
#ifdef IMA_I860
#define n_cid	n_ptype			/* the global qm_cubeid */
	char *n_name;				/* cube name */
#endif
};

/* tid fields */

#define TIDONNODE	0x00020000	/* this bit is set for node tasks */
#define TIDNODE		0x000007ff	/* 11 bits for node number */
#define TIDPTYPE	0x0001f800	/* 6 bits for process type */
#define NUMPTYPE	64			/* (PGON) num of active proc types allowed */

#define PVMDPTYPE	0			/* process type of pvmd */
#define PDMNODE		64			/* pvmd debug mask */
#define MAXFRAGSIZE	16384		/* max fragment size (16K) */
#define SIZEHINFO	5			/* size of hostinfo array */
#define TIMEOUT		10000		/* for select(); in usec */

/* pvm internal message types */

#define PMTDN		1			/* pvmd to node */
#define PMTND		2			/* node to pvmd */
#define PMTNN		3			/* node to node */
#define PMTHOST		4			/* broadcast myhostpart to all nodes */
#define PMTMCAST	5			/* broadcast multicast packets to all nodes */
#define PMTPHYS		6			/* (iPSC/860) msg containing physical node # */

/* determine if task is a node process */
#define TIDISNODE(tid)	((tid) & (TIDONNODE))
/* extract the ptype bits */
#define TIDTOTYPE(tid)	(tid & tidtmask) >> (ffs(tidtmask) - 1)

void mpp_init __ProtoGlarp__((int *argc, char **argv));
struct nodeset *mpp_new __ProtoGlarp__((int count, int ptid));
void mpp_free __ProtoGlarp__((int tid));
int mpp_load __ProtoGlarp__((int flags, char *name, char **argv, int count,
	int *tids, int ptid));
void mpp_input __ProtoGlarp__((void));
int mpp_mcast __ProtoGlarp__((int src, struct pkt *pp, int *tids, int ntask));
void mpp_output __ProtoGlarp__((struct task *tp, struct pkt *pp));
struct task *mpp_find __ProtoGlarp__((int pid));
int mpp_probe __ProtoGlarp__((void));
void mpp_kill __ProtoGlarp__((struct task *tp, int signum));

