
/*
 *           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.
 */

/*
 *	mesg.c
 *
 *	Pvmd message descriptors.
 *
$Log: mesg.c,v $
 * Revision 1.1  1993/08/30  23:26:49  manchek
 * Initial revision
 *
 */

#include "protoglarp.h"
#include "pvmalloc.h"
#include "pvmfrag.h"
#include "mesg.h"
#include "listmac.h"


extern void pvmbailout();


/***************
 **  Private  **
 **           **
 ***************/

static char rcsid[] = "$Id: mesg.c,v 1.1 1993/08/30 23:26:49 manchek Exp $";


/*****************
 **  Interface  **
 **             **
 *****************/

struct mesg *
mesg_new(master)
	int master;		/* true if a master (no data) node */
{
	struct mesg *mp;

	if (!(mp = TALLOC(1, struct mesg, "mesg"))) {
		pvmlogerror("mesg_new() can't get memory\n");
		pvmbailout(0);
	}
	mp->m_ref = 1;
	if (master) {
		mp->m_link = mp->m_rlink = mp;
		mp->m_frag = 0;
		mp->m_enc = 0;
	} else {
		mp->m_link = mp->m_rlink = 0;
		mp->m_frag = fr_new(0);
		mp->m_enc = 1;
	}
	mp->m_len = mp->m_dst = mp->m_src = mp->m_cod
			= mp->m_wid = mp->m_flag = mp->m_cpos = 0;
	mp->m_cfrag = 0;
	return mp;
}


/*	mesg_free()
*
*	Free a message or list of messages.  If m_frag is nonzero, this is
*	a slave node; unlink and free it and its frag list.  Else, it's
*	a master node; free all slave nodes too.
*/

void
mesg_free(mp)
	struct mesg *mp;
{
	if (mp->m_frag) {	/* slave mesg */
		if (mp->m_link && mp->m_rlink) {
			LISTDELETE(mp, m_link, m_rlink);
		}
		fr_unref(mp->m_frag);

	} else {	/* master */
		while (mp->m_link != mp)
			mesg_free(mp->m_link);
	}
	PVM_FREE(mp);
}


/*	mesg_unref()
*
*/

void
mesg_unref(mp)
	struct mesg *mp;
{
	if (--mp->m_ref < 1)
		mesg_free(mp);
}


struct mca *
mca_new()
{
	struct mca *mcap;

	if (mcap = TALLOC(1, struct mca, "mca")) {
		mcap->mc_link = mcap->mc_rlink = mcap;
		mcap->mc_tid = mcap->mc_ndst = 0;
		mcap->mc_dsts = 0;
	}
	return mcap;
}


void
mca_free(mcap)
	struct mca *mcap;
{
	LISTDELETE(mcap, mc_link, mc_rlink);
	if (mcap->mc_dsts)
		PVM_FREE(mcap->mc_dsts);
	PVM_FREE(mcap);
}


