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.