[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

### 3.8.2 Ports and Packets

A pointer type declared as a `port` points to a structure in the following form, where a `flag` is an unsigned short integer type, and a `counter` is an unsigned long integer.

    struct avm_packet
    {
      port parent;
      counter errors;
      portal descendents;
      list impetus, contents;
      flag predicating;
    };

For reasons that make sense to C, the `avm_packet` and `port` types are declared in `lists.h`, but a few memory management operations on them are available by way of functions declared in ‘`ports.h`’. The intended meaning of this structure is described presently, but first the memory management functions are as follows.

Function: port avm_newport (counter errors, port parent, int predicating)

  This function attempts to allocate storage for a new packet structure and returns its address if successful. If storage can not be allocated, a `NULL` pointer is returned. The `errors`, `parent`, and `predicating` fields are initialized with the parameters supplied by the caller. The rest of the structure is filled with zeros. A local memory cache is used for improved performance.

Function: void avm_sever (port appendage)

  This function reclaims the storage associated with a `port`, either freeing it entirely or holding it in a local cache. None of the entities that may be referenced by pointers within the structure are affected. Only this function should be used by client programs for disposing of ports, not the `free` function directly, or some internal bookkeeping will be disrupted. An internal error results if the argument is a `NULL` pointer.

Function: void avm_initialize_ports ()

  This function must be called prior to calling either of the two above, in order to initialize some static variables.

Function: void avm_count_ports ()

  This function may be called after the last call to any of the other functions in this section in order to detect and report unreclaimed storage associated with ports. A non-fatal warning will be written to standard error if any is detected, but otherwise there is no effect.

The interesting aspect of this data structure is the role it plays in capturing the state of a computation. For this purpose, it corresponds to a single node in a partially computed result to be represented by a `list` when it’s finished. The nodes should be envisioned as a doubly-linked binary tree, except that the pair of `descendents` for each node is not yet known with certainty, so a list of alternatives must be maintained.

Because the computation is not completed while this data structure exists, there are always some empty fields in it. For example, the `descendents` and the `contents` fields embody the same information, the latter doing so in a compact as opposed to a more expanded form. Hence, it would be redundant for both fields to be non-empty at the same time. The data structure is built initially with `descendents` and no `contents`, only to be transformed into one with `contents` and no `descendents`.

The significance of each field in the structure can be summarized as follows.

`contents`

  If the computational result destined for the `port` pointing to this packet is not complete, then this field is `NULL` and the `descendents` are being computed. Otherwise, it contains the result of the computation.

`descendents`

  This field points to a list of pairs of ports serving as the destinations for an ensemble of concurrent computations.(3) The `head` and `tail` of the `contents` are to be identified respectively with the `contents` of the `left` and `right` `port` in the first pair to finish being computed.

`parent`

  If this packet is addressed by the `left` or the `right` of `port` in one of the `descendents` of some other packet, then this field points to that packet.

`errors`

  A non-zero value in this field indicates that the result destined for the `contents` of this packet is expected to be an error message. If the exact level of error severity incurred in the computation of the `contents` matches this number, then the contents can be assigned the result, but otherwise the result should propagate to the `contents` of the `parent`.

`predicating`

  A non-zero value in this field implies that the result destined for the `contents` of this packet is being computed in order to decide which arm of a conditional function should be chosen. I.e., a `NULL` result calls for the one that is invoked when the predicate is false.

`impetus`

  If the result destined for the `contents` of this packet is being computed in order to transform a virtual code fragment from its original form to an equivalent representation capable of being evaluated more directly, this field points to a `list` node at the root of the virtual code in its original form.

One of the hitherto undocumented fields in a `list` node structure declared in ‘`lists.h`’ is called the `interpretation`, and is of type `list`. A client program delving into sufficient depth of detail to be concerned with ports and packets may reasonably assign the `interpretation` field of the `list` referenced by the `impetus` field in a packet to be a copy of the `contents` of the packet when they are eventually obtained. Doing so will save some time by eliminating the need for it to be recomputed if the same virtual code should be executed again.

If this course is taken, the `facilitator` field in a `list` node, also hitherto undocumented, should contain the address of the packet referring to the list node as its `impetus`. The reason for this additional link is so that it can be followed when the `impetus` of the packet is be cleared by `avm_dispose` in the event that the `list` node is freed before the computation completes. This action is performed in order to preclude a dangling pointer in the `impetus` field.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated on November 8, 2012 using texi2html 1.82.