Langue: en

Version: 59021 (mandriva - 22/10/07)

Autres sections - même nom

Section: 2 (Appels système)


nsend, ntry_send, nrecv, ntry_recv - Send and receive LAM network messages.


 #include <net.h>
 int nsend (struct nmsg *header);
 int ntry_send (struct nmsg *header);
 int nrecv (struct nmsg *header);
 int ntry_recv (struct nmsg *header);


subroutine NSND (nnode, nevent, ntype, nlength, nflags, ndata, ndsize, nmsg, ierror)
subroutine NRCV (nevent, ntype, nlength, nflags, ndata, ndsize, nmsg, ierror)
integer nevent, ntype, nlength, nflags, ndata(*), ndsize, ierror
<type> nmsg(*)


The network message-passing functions add routing and packetization to the datalink functions, dsend(2) and drecv(2). nrecv() blocks if there is no synchronizing message to receive. nsend() will block if there is no synchronizing receiving process or forwarding process to take its message (see "Blocking").

ntry_send() and ntry_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. See nprobe(2) for similar functionality.

Network Message Descriptor

All of the functions accept a pointer to a network message descriptor which is an extension of the local level message descriptor used by ksend(2) and krecv(2). The network message descriptor is defined in <net.h>.
 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;

This field is unchanged by nrecv() but is set to the event of the synchronizing process (either the intended receiver or a forwarding process) after calling nsend(). See dsend(2).


This field is unchanged by nrecv() but is set to the output link number if the message was forwarded to a datalink output process after calling nsend(). See dsend(2).

This field is used by nsend() to identify the remote node running the intended receiver. It is not used by nrecv(). 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. Two special node identifiers are defined in <net.h>. LOCAL refers to the local node and causes nsend() to bypass its routing step. ORIGIN refers to the node from which lamboot(1) was invoked.

This field is never altered.

An event is an arbitrary positive integer used by the LAM kernel to synchronize processes within a node. Synchronization occurs when two events are equal. nsend() transfers the message to the destination node and then to the highest priority process blocked on the event in the message's nh_event field and a matching type (see below). Thus, the sender calling nsend() must set nh_event to the same value as the receiver calling nrecv().

This field is never altered.

This field further filters messages that match on event. A message will be transferred to a receiver 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.

This field remains unchanged after calling nsend(), but is set to the sender's nh_type after calling nrecv().

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 to the receiver. Messages longer than the maximum network packet size, defined by MAXNMSGLEN in <net.h>, will be implicitly broken down into a series of smaller messages, which will be recombined by the receiver. Because of this packetization, one call to nsend() can introduce many messages into the network, a possible source of confusion during debugging.

This field remains unchanged after calling nsend(), but is set to the minimum of the sender's and receiver's lengths after calling nrecv().

This field is normally set to 0. When the NOBUF flag (defined in <net.h>) is set in nh_flags buffers will not be used. Flags used to assure that the data representation is correct for the receiving node are discussed under "Data Representation".

This field is never altered.

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 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 nrecv() the nh_data field is overwritten with the sender's values of the same field. The sender's nh_data will not change.

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

This 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.

nh_data holds 8 32-bit integers (default).
nh_data holds 8 single 32-bit real numbers.
nh_data holds 4 64-bit real numbers.
nh_data representation will not be changed.
nh_msg points to 32-bit integers.
nh_msg points to 32-bit real numbers.
nh_msg points to 64-bit real numbers.
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 function suites ltot(3), ttol(3), etc.

Example Usage

The following example passes a message between two nodes with similar data representations, utilizing a minimum level of synchronization. This is intended only as a summary of a simple case. Many variations can be constructed using the detailed information given in the above section.
 /* Sender */
 #include <net.h>
 struct nmsg nhead;
 char *msg = "Hello, world";
 nhead.nh_node = 10
 nhead.nh_event = 6
 nhead.nh_type = 0
 nhead.nh_flags = 0
 nhead.nh_length = strlen(msg) + 1;
 nhead.nh_msg = msg;
 /* Receiver */
 /* Assume this code is running on node 10. */
 #include <net.h>
 struct nmsg nhead;
 char msg[16]
 nhead.nh_event = 6
 nhead.nh_type = 0
 nhead.nh_flags = 0
 nhead.nh_length = sizeof(msg);
 nhead.nh_msg = msg;


A process calling nrecv() blocks until the message sent by the process calling nsend() entirely arrives. A process calling nsend() blocks only until its message is picked up by:
a local receiver calling nrecv()
a local buffer process
a local forwarding process such as a datalink

The only thing that is guaranteed by a successful return from nsend() is that the message has entirely left the calling process.

The loose blocking behaviour of nsend() 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 nrecv() that may never happen. If that unfortunate process is a buffer, it can be located by the user and swept clean (see sweep(1)). However, if the process is a link proprietor, the link is henceforth plugged and useless.

Besides the legitimate buffer process, datalink processes can each hold one or more messages. NOBUF does not affect these implicit buffers.


Errors return LAMERROR and set errno appropriately. The lam_perror() and lam_errorstr() functions can be used to retrieve the error string associated with errno.

Some common errno values include:

ntry_send() or ntry_recv() failed because the message could not be sent or received, respectively. A call to nsend() or nrecv() would have blocked.
The calling program is not attached to the LAM run time environment.


Multi-packet messages can inter-mingle packets if sent to the same node, event and type. The solution for this type of communication structure is to use tsend(2) and trecv(2).


dsend(2), nprobe(2), tsend(2)