1NSEND(2) LAM NETWORK LIBRARY NSEND(2)
2
3
4
6 nsend, ntry_send, nrecv, ntry_recv - Send and receive LAM network mes‐
7 sages.
8
10 #include <net.h>
11
12 int nsend (struct nmsg *header);
13 int ntry_send (struct nmsg *header);
14 int nrecv (struct nmsg *header);
15 int ntry_recv (struct nmsg *header);
16
18 subroutine NSND (nnode, nevent, ntype, nlength, nflags, ndata, ndsize,
19 nmsg, ierror)
20
21 subroutine NRCV (nevent, ntype, nlength, nflags, ndata, ndsize, nmsg,
22 ierror)
23
24 integer nevent, ntype, nlength, nflags, ndata(*), ndsize, ierror
25<type> nmsg(*)
26
28 The network message-passing functions add routing and packetization to
29 the datalink functions, dsend(2) and drecv(2). nrecv() blocks if there
30 is no synchronizing message to receive. nsend() will block if there is
31 no synchronizing receiving process or forwarding process to take its
32 message (see "Blocking").
33
34 ntry_send() and ntry_recv() never cause the calling process to block.
35 The message is either immediately transferred, or an error is immedi‐
36 ately returned, indicating that the process would have blocked. See
37 nprobe(2) for similar functionality.
38
39 Network Message Descriptor
40 All of the functions accept a pointer to a network message descriptor
41 which is an extension of the local level message descriptor used by
42 ksend(2) and krecv(2). The network message descriptor is defined in
43 <net.h>.
44
45 struct nmsg {
46 int nh_dl_event;
47 int nh_dl_link;
48 int nh_node;
49 int nh_event;
50 int nh_type;
51 int nh_length;
52 int nh_flags;
53 int nh_data[NHDSIZE];
54 char *nh_msg;
55 };
56
57 nh_dl_event
58 unused
59
60 This field is unchanged by nrecv() but is set to the event of
61 the synchronizing process (either the intended receiver or a
62 forwarding process) after calling nsend(). See dsend(2).
63
64 nh_dl_link
65 unused
66
67 This field is unchanged by nrecv() but is set to the output link
68 number if the message was forwarded to a datalink output process
69 after calling nsend(). See dsend(2).
70
71 nh_node
72 This field is used by nsend() to identify the remote node run‐
73 ning the intended receiver. It is not used by nrecv(). A
74 receiving process thus cannot directly specify the source node
75 of a message. Instead, receiving processes are "matched" to
76 messages by one or both of nh_event and nh_type. Two special
77 node identifiers are defined in <net.h>. LOCAL refers to the
78 local node and causes nsend() to bypass its routing step. ORI‐
79 GIN refers to the node from which lamboot(1) was invoked.
80
81 This field is never altered.
82
83 nh_event
84 An event is an arbitrary positive integer used by the LAM kernel
85 to synchronize processes within a node. Synchronization occurs
86 when two events are equal. nsend() transfers the message to the
87 destination node and then to the highest priority process
88 blocked on the event in the message's nh_event field and a
89 matching type (see below). Thus, the sender calling nsend()
90 must set nh_event to the same value as the receiver calling
91 nrecv().
92
93 This field is never altered.
94
95 nh_type
96 This field further filters messages that match on event. A mes‐
97 sage will be transferred to a receiver only if the nh_type
98 fields of the sender and receiver processes have at least one
99 bit set in an identical position. In other words, the bitwise
100 logical AND of the type fields specified by the two parties must
101 not equal zero. A zero value matches any other value of
102 nh_type.
103
104 This field remains unchanged after calling nsend(), but is set
105 to the sender's nh_type after calling nrecv().
106
107 nh_length
108 This field holds the length (in bytes) of the message to be
109 sent. If the sender and the receiver specify different lengths,
110 the lesser amount will be transferred to the receiver. Messages
111 longer than the maximum network packet size, defined by MAXNMS‐
112 GLEN in <net.h>, will be implicitly broken down into a series of
113 smaller messages, which will be recombined by the receiver.
114 Because of this packetization, one call to nsend() can introduce
115 many messages into the network, a possible source of confusion
116 during debugging.
117
118 This field remains unchanged after calling nsend(), but is set
119 to the minimum of the sender's and receiver's lengths after
120 calling nrecv().
121
122 nh_flags
123 This field is normally set to 0. When the NOBUF flag (defined
124 in <net.h>) is set in nh_flags buffers will not be used. Flags
125 used to assure that the data representation is correct for the
126 receiving node are discussed under "Data Representation".
127
128 This field is never altered.
129
130 nh_data
131 This field is a convenient data pouch within the network message
132 descriptor. Its array size is NHDSIZE words, which is defined
133 in <net.h> and is set to 8. It can be used for sending short
134 messages (in which case nh_length is set to 0) or for appending
135 control information to the message body.
136
137 After calling nrecv() the nh_data field is overwritten with the
138 sender's values of the same field. The sender's nh_data will
139 not change.
140
141 nh_msg This field holds the address of the first byte of data to be
142 sent or received. The data must be stored contiguously in mem‐
143 ory.
144
145 This field is never altered.
146
147 Data Representation
148 On nodes of different architectures, data may have different represen‐
149 tations. For example, integers may be stored with the most significant
150 byte first in memory (big-endian) or with the most significant byte
151 last in memory (little-endian). Also, the representation of floating
152 point numbers may conform to the IEEE standard or may follow a vendor
153 specific format. All fields in the network message structure, except
154 the data referenced by nh_msg, are automatically converted if passed to
155 a node with different data representation. The nh_data field is
156 assumed to hold all integers.
157
158 The nh_flags field of the message structure can be set to the following
159 data representation flags. Each flag assumes a data type, and will
160 make the appropriate change in the data representation of the given
161 field. They will have no effect if data conversion is not needed.
162
163 DINT4DATA nh_data holds 8 32-bit integers (default).
164
165 DFLT4DATA nh_data holds 8 single 32-bit real numbers.
166
167 DFLT8DATA nh_data holds 4 64-bit real numbers.
168
169 DRAWDATA nh_data representation will not be changed.
170
171 DINT4MSG nh_msg points to 32-bit integers.
172
173 DFLT4MSG nh_msg points to 32-bit real numbers.
174
175 DFLT8MSG nh_msg points to 64-bit real numbers.
176
177 DRAWMSG nh_msg representation will not be changed (default).
178
179 If nh_data or nh_msg contains a mixture of data types, the user will
180 have to change the representation using the function suites ltot(3),
181 ttol(3), etc.
182
183 Example Usage
184 The following example passes a message between two nodes with similar
185 data representations, utilizing a minimum level of synchronization.
186 This is intended only as a summary of a simple case. Many variations
187 can be constructed using the detailed information given in the above
188 section.
189
190 /* Sender */
191
192 #include <net.h>
193
194 struct nmsg nhead;
195 char *msg = "Hello, world";
196
197 nhead.nh_node = 10
198 nhead.nh_event = 6
199 nhead.nh_type = 0
200 nhead.nh_flags = 0
201 nhead.nh_length = strlen(msg) + 1;
202 nhead.nh_msg = msg;
203
204 nsend(&nhead);
205
206 /* Receiver */
207 /* Assume this code is running on node 10. */
208
209 #include <net.h>
210
211 struct nmsg nhead;
212 char msg[16]
213
214 nhead.nh_event = 6
215 nhead.nh_type = 0
216 nhead.nh_flags = 0
217 nhead.nh_length = sizeof(msg);
218 nhead.nh_msg = msg;
219
220 nrecv(&nhead);
221
222 Blocking
223 A process calling nrecv() blocks until the message sent by the process
224 calling nsend() entirely arrives. A process calling nsend() blocks
225 only until its message is picked up by:
226
227 a) a local receiver calling nrecv()
228
229 b) a local buffer process
230
231 c) a local forwarding process such as a datalink
232
233 The only thing that is guaranteed by a successful return from nsend()
234 is that the message has entirely left the calling process.
235
236 The loose blocking behaviour of nsend() introduces a fundamental danger
237 of LAM message passing: a sender can transmit a message that may never
238 be received due to programming error or deadlock. This message will
239 never be dropped or timed out. Some LAM process will always be stuck
240 with it, waiting for a synchronizing nrecv() that may never happen. If
241 that unfortunate process is a buffer, it can be located by the user and
242 swept clean (see sweep(1)). However, if the process is a link propri‐
243 etor, the link is henceforth plugged and useless.
244
245 Besides the legitimate buffer process, datalink processes can each hold
246 one or more messages. NOBUF does not affect these implicit buffers.
247
249 Errors return LAMERROR and set errno appropriately. The lam_perror()
250 and lam_errorstr() functions can be used to retrieve the error string
251 associated with errno.
252
253 Some common errno values include:
254
255 EWOULDBLOCK ntry_send() or ntry_recv() failed because the message
256 could not be sent or received, respectively. A call to
257 nsend() or nrecv() would have blocked.
258
259 ENOTATTACHED The calling program is not attached to the LAM run time
260 environment.
261
263 Multi-packet messages can inter-mingle packets if sent to the same
264 node, event and type. The solution for this type of communication
265 structure is to use tsend(2) and trecv(2).
266
268 dsend(2), nprobe(2), tsend(2)
269
270
271
272LAM 7.1.2 March, 2006 NSEND(2)