DSEND(2)

NAME
dsend, dtry_send, drecv, dtry_recv - Send and receive LAM datalink messages.

SYNOPSIS
#include <net.h>
#include <events.h>
int dsend (struct nmsg *header);
int dtry_send (struct nmsg *header);
int drecv (struct nmsg *header);
int dtry_recv (struct nmsg *header);

DESCRIPTION
These datalink functions pass a network message from one process to another and are the basis for all forms of LAM network communication. Although they can be invoked directly, they are most often called by the network and transport functions. The datalink functions do not supply message routing, buffering or packetization. The user supplies the event of the forwarding process and the message length is restricted to MAXNMSGLEN, defined in <net.h>.

dsend() and drecv() are typically used to send messages to, or receive messages from, nearest neighbour nodes (see "Typical Usage"). dtry_send() and dtry_recv() never cause the calling process to block. The message is either immediately transferred, or an error is immediately returned, indicating that the process would have blocked.

  Network Message Structure
All of the functions accept a pointer to a message structure which is an extension of the local level message structure used by ksend(2) and krecv(2). The network message structure is defined in <net.h> as:

    struct nmsg {
    	int	nh_dl_event;
    	int	nh_dl_link;
    	int	nh_node;
    	int	nh_event;
    	int	nh_type;
    	int	nh_length;
    	int	nh_flags;
    	int	nh_data[NHDSIZE];
    	char	*nh_msg;
    };

The usage of each field in the network message structure is described below.

nh_dl_event
    This field is used by dsend() to synchronize the sending process and a) a forwarding process such as a link output process, or b) a local receiving process. In the first case, the synchronization is between nh_dl_event and the published event of the forwarding process. The forwarding event is returned by getroute(2). In the second case, the synchronization is between nh_dl_event and the local receiver's nh_event field. The nh_dl_event field is not used by drecv().

    The nh_dl_event field remains unchanged after calling dsend() or drecv().

nh_dl_link
    If nh_dl_event refers to a link output process, a specific link number must be given in the nh_dl_link field. Link output processes may handle multiple links. This field is not used by drecv().

    The nh_dl_link field remains unchanged after calling dsend() or drecv().

nh_node
    This field is used by dsend() to identify the remote node running the intended receiver. Typically, the destination node is an immediate neighbour of the local node. The nh_node field is not used by drecv(). A receiving process thus cannot directly specify the source node of a message. Instead, receiving processes are "matched" to messages by one or both of nh_event and nh_type.

    The nh_node field is never altered.

nh_event
    An event is an arbitrary positive integer used by the LAM daemon to synchronize processes within a node. Synchronization occurs when two events are equal. In a datalink transfer, nh_dl_event in the sender equals nh_event in the local receiver. When the local receiver is a forwarding process, the message begins a journey through the network system. Much more than one simple datalink transfer is taking place and the sender must give more information beyond nh_dl_event in the nh_node and nh_event fields. The message may be transmitted through a physical communication link to a neighbour node. On the destination remote node, the nh_event given by the original sender is copied to nh_dl_event and another typical datalink transfer occurs between a system process and the ultimate intended receiver calling drecv(). Thus, the sender calling dsend() must set nh_event to the same value as the intended receiver calling drecv(). If the datalink functions present too much complexity, try nsend(2) and nrecv(2).

    The nh_event field is never altered.

nh_type
    This field further filters messages that match on event. A message will be passed only if the nh_type fields of the sender and receiver processes have at least one bit set in an identical position. In other words, the bitwise logical AND of the type fields specified by the two parties must not equal zero. A zero value matches any other value of nh_type. The dsend() function compares nh_dl_event and nh_event to decided if the receiver is a forwarding process. If they are equal, nh_type is used as described above. Otherwise, usage of nh_type is deferred until the message arrives at the destination node for synchronization with the ultimate intended receiver and special type values are immediately used to codify the message and control synchronization with the forwarding process. If nh_event is negative, a type signifying a system message is used, otherwise the type identifies a user message. Application programs should not directly specify negative values for nh_event. If the datalink functions present too much complexity, try nsend(2) and nrecv(2).

    The nh_type field remains unchanged after calling dsend(), but is set to the sender's nh_type after calling drecv().

nh_length
    This field holds the length (in bytes) of the message to be sent. If the sender and the receiver specify different lengths, the lesser amount will be transferred. The maximum length of messages transferred with dsend() and drecv() is MAXNMSGLEN, defined in <net.h> and usually set to 8192 bytes. Forwarding processes in the LAM network subsystem always use MAXNMSGLEN.

    The nh_length field remains unchanged after calling dsend(), but is set to the minimum of the sender's and receiver's lengths after calling drecv().

nh_flags
    This field is normally set to 0. Flags used to ensure that the data representation is correct for the receiving node are discussed under "Data Representation".

    The nh_flags field is never altered.

nh_data
    This field is a convenient data pouch within the network message descriptor. Its array size is NHDSIZE words, which is defined in <net.h> and is currently set to 8. It can be used for sending short messages (in which case nh_length is set to 0) or for appending control information to the message body.

    After calling drecv() the nh_data field is overwritten with the sender's values of the same field. The sender's nh_data will not change.

nh_msg
    This field holds the address of the first byte of data to be sent or received. The data must be stored contiguously in memory.

    The nh_msg field is never altered.

  Data Representation
On nodes of different architectures, data may have different representations. For example, integers may be stored with the most significant byte first in memory (big-endian) or with the most significant byte last in memory (little-endian). Also, the representation of floating point numbers may conform to the IEEE standard or may follow a vendor specific format. All fields in the network message structure, except the data referenced by nh_msg, are automatically converted if passed to a node with different data representation. The nh_data field is assumed to hold all integers.

The nh_flags field of the message structure can be set to the following data representation flags. Each flag assumes a data type, and will make the appropriate change in the data representation of the given field. They will have no effect if data conversion is not needed.

DINT4DATA
    nh_data holds 8 32-bit integers (default).

DFLT4DATA
    nh_data holds 8 single 32-bit real numbers.

DFLT8DATA
    nh_data holds 4 64-bit real numbers.

DRAWDATA
    nh_data representation will not be changed.

DINT4MSG
    nh_msg points to 32-bit integers.

DFLT4MSG
    nh_msg points to 32-bit real numbers.

DFLT8MSG
    nh_msg points to 64-bit real numbers.

DRAWMSG
    nh_msg representation will not be changed (default).

If nh_data or nh_msg contains a mixture of data types, the user will have to change the representation using the functions ltoti4(3), ttoli4(3), etc.

  Typical Usage
The typical usage of the datalink functions is for nearest neighbour message passing, when the user wishes to avoid the expense of automatic message routing (as provided by nsend(2)) and other network level overheads. To synchronize the sender and receiver, the sender must set nh_node to the destination neighbour's node ID, nh_dl_event to the link process event connecting the neighbour node, nh_dl_link to the specific link number and nh_event to its counterpart in the receiver.

  Blocking
A process calling drecv() blocks until the message sent by the process calling dsend() entirely arrives. A process calling dsend() blocks only until its message is picked up by a) a local receiver calling drecv() or b) the local forwarding process identified by nh_dl_event. The only thing that is guaranteed by a successful return from dsend() is that the message has entirely left the calling process.

The loose blocking behaviour of dsend() introduces a fundamental danger of LAM message passing: a sender can transmit a message that may never be received due to programming error or deadlock. This message will never be dropped or timed out. Some LAM process will always be stuck with it, waiting for a synchronizing drecv() that may never happen. If the process is a link proprietor, the link could become plugged and useless. A link input process may hold one message. A link output process may hold several messages, depending on its internal implementation.

ERRORS

EWOULDBLOCK
    One of the non-blocking functions, dtry_send() or dtry_recv(), failed because the message could not be sent or received, respectively. A call to dsend() or drecv() would have blocked.

SEE ALSO
nsend(2), tsend(2)