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

This is irt.c 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.
 *
 * irt.c  -  Code for IRT (Incoming Reference Table) manipulation
 */

#include "pcn.h"

#ifdef PARALLEL

static	int_t	actual_irt_increment;


/*
 * _p_init_irt()
 *
 * Initialize the IRT.
 * See extern.h for detailed comments on the various
 * IRT management variables, and how they are used.
 *
 * It is assumed that _p_nodes and _p_my_id are already set when
 * this procedure is called.  After allocating the initial entries, the
 * first _p_nodes entries, except for the _p_my_id'th entry, will be
 * used by the boot up code to create streams from the other nodes.
 * So leave these entries alone, and create the IRT free list with any
 * remaining entries.
 */
void _p_init_irt()
{
    irt_t *entry;
    int_t i, next_irt_index;

    /*
     * Set the _p_irt_size
     */
    if (_p_irt_initial_size < 0)
	_p_irt_size = _p_nodes * (-(_p_irt_initial_size));
    else
	_p_irt_size = _p_irt_initial_size;
    if (_p_irt_size < _p_nodes)
	/* Adjust it if its not reasonable */
	_p_irt_size = 10 * _p_nodes;

    if ((_p_irt = (irt_t *) malloc (_p_irt_size * IrtEntrySize * CELL_SIZE))
	== (irt_t *) NULL)
    {
	_p_malloc_error();
    }
    
    /*
     * Set the actual_irt_increment to the number of entries to increment by
     */
    if (_p_irt_increment)
	actual_irt_increment = _p_nodes * (-(_p_irt_increment));
    else
	actual_irt_increment = _p_irt_increment;
    if (actual_irt_increment <= 0)
	/* Adjust it if its not reasonable */
	actual_irt_increment = 10 * _p_nodes;

    /*
     * Set up the _p_irt_free_list so that it contains the _p_my_id'th
     * IRT entry, plus all entries >= _p_nodes.  (The first _p_nodes
     * entries, except _p_my_id, are used as incoming streams from
     * other nodes during bootstrap.)
     */
    _p_irt_free_list = _p_my_id;
    entry = IrtAddress(_p_my_id);
    entry->weight = 0;
    entry->u.next_free = _p_nodes;
    next_irt_index = _p_nodes;
    entry = IrtAddress(_p_nodes);
    for (i = _p_irt_size - _p_nodes; i > 0; i--, entry++)
    {
	entry->weight = 0;
	entry->u.next_free = ++next_irt_index;
    }
    entry--;
    entry->u.next_free = -1;

} /* _p_init_irt() */


/*
 * _p_alloc_irt_entry()
 *
 * Allocate an IRT entry, with the given 'ptr' and 'weight'.
 *
 * Return:	 index of the IRT entry.
 */
int_t _p_alloc_irt_entry(ptr, weight)
cell_t *ptr;
u_int_t weight;
{
    int_t new_index;
    irt_t *new_entry;
    
    if (_p_irt_free_list == -1)
    {
#ifdef NO_VIRTUAL_MEMORY
	
	char buf[256];
	sprintf(buf,
		"The IRT table is full. (Current size = %ld entries.)  Use the -irt_size flag to increase the size of this table.",
		(long) _p_irt_size);
	_p_fatal_error(buf);
	
#else  /* NO_VIRTUAL_MEMORY */
	
	irt_t *entry;
	int_t i, new_size, next_irt_index;
	
	new_size = _p_irt_size + actual_irt_increment;
	if ((_p_irt = (irt_t *) realloc (_p_irt,
					 new_size * IrtEntrySize * CELL_SIZE))
	    == (irt_t *) NULL)
	{
	    _p_malloc_error();
	}
	new_index = _p_irt_size;
	new_entry = IrtAddress(_p_irt_size);
	_p_irt_free_list = next_irt_index = _p_irt_size + 1;
	entry = IrtAddress(_p_irt_free_list);
	for (i = actual_irt_increment - 1; i > 0; i--, entry++)
	{
	    entry->weight = 0;
	    entry->u.next_free = ++next_irt_index;
	}
	entry--;
	entry->u.next_free = -1;
	_p_irt_size += actual_irt_increment;
	
#endif /* NO_VIRTUAL_MEMORY */    
    }
    else
    {
	new_index = _p_irt_free_list;
	
#ifdef DEBUG	
	if (new_index >= _p_irt_size)
	{
	    _p_fatal_error("Internal Error: _p_alloc_irt_entry(): Found an illegal IRT index in the IRT free list");
	}
#endif /* DEBUG */
	
	new_entry = IrtAddress(new_index);
	_p_irt_free_list = new_entry->u.next_free;
    }
    
    new_entry->weight = weight;
    new_entry->u.ptr = ptr;

#ifdef DEBUG
    if (ParDebug(5))
    {
	fprintf(_p_stdout, "(%lu,%lu) Allocating irt %lu with weight %lu\n",
		(unsigned long) _p_my_id, (unsigned long) _p_reduction,
		(unsigned long) new_index, (unsigned long) weight);
	fflush(_p_stdout);
    }
#endif /* DEBUG */
    
    return (new_index);
} /* _p_alloc_irt_entry() */


/*
 * _p_cancel_irt_entry()
 *
 * Cancel the IRT entry, 'entry_index', by 'weight'.  If the resulting
 * weight for this IRT entry is 0, then this entry can be put back
 * onto the free list.
 */
void _p_cancel_irt_entry(entry_index, weight)
int_t entry_index;
u_int_t weight;
{
    irt_t *entry;
    
#ifdef DEBUG
    if (entry_index >= _p_irt_size)
    {
	_p_fatal_error("Internal Error: _p_cancel_irt_entry(): Passed an illegal IRT index");
    }
    if (ParDebug(5))
    {
	fprintf(_p_stdout, "(%lu,%lu) Canceling  irt %lu with weight %lu\n",
		(unsigned long) _p_my_id, (unsigned long) _p_reduction,
		(unsigned long) entry_index, (unsigned long) weight);
	fflush(_p_stdout);
    }
#endif /* DEBUG */

    entry = IrtAddress(entry_index);

#ifdef DEBUG
    if (entry->weight < weight)
    {
	fprintf(_p_stdout,
		"(%lu,%lu) WARNING: _p_cancel_irt_entry(): weight to cancel (%lu) is greater than total weight (%lu) for irt %lu\n",
		(unsigned long) _p_my_id, (unsigned long) _p_reduction,
		(unsigned long) weight, (unsigned long) entry->weight,
		(unsigned long) entry_index);
	fflush(_p_stdout);
	return;
    }
#endif /* DEBUG */
    
    entry->weight -= weight;

    if (entry->weight == 0)
    {
	entry->u.next_free = _p_irt_free_list;
	_p_irt_free_list = entry_index;
    }
} /* _p_cancel_irt_entry() */

#endif /* PARALLEL */

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