1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 FRESCOR consortium partners:
4 // Universidad de Cantabria, SPAIN
5 // University of York, UK
6 // Scuola Superiore Sant'Anna, ITALY
7 // Kaiserslautern University, GERMANY
8 // Univ. Politécnica Valencia, SPAIN
9 // Czech Technical University in Prague, CZECH REPUBLIC
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
18 // FRESCOR project (FP6/2005/IST/5-034026) is funded
19 // in part by the European Union Sixth Framework Programme
20 // The European Union is not liable of any use that may be
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FRSH API
36 // FRSH API is free software; you can redistribute it and/or modify
37 // it under the terms of the GNU General Public License as published by
38 // the Free Software Foundation; either version 2, or (at your option)
41 // FRSH API is distributed in the hope that it will be useful, but
42 // WITHOUT ANY WARRANTY; without even the implied warranty of
43 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44 // General Public License for more details.
46 // You should have received a copy of the GNU General Public License
47 // distributed with FRSH API; see file COPYING. If not, write to the
48 // Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
51 // As a special exception, if you include this header file into source
52 // files to be compiled, this header file does not by itself cause
53 // the resulting executable to be covered by the GNU General Public
54 // License. This exception does not however invalidate any other
55 // reasons why the executable file might be covered by the GNU General
57 // -----------------------------------------------------------------------
59 //==============================================
60 // ******** ******* ******** ** **
61 // **///// /**////** **////// /** /**
62 // ** /** /** /** /** /**
63 // ******* /******* /********* /**********
64 // **//// /**///** ////////** /**//////**
65 // ** /** //** /** /** /**
66 // ** /** //** ******** /** /**
67 // // // // //////// // //
69 // FRSH(FRescor ScHeduler), pronounced "fresh"
70 //==============================================
71 #ifndef _FRSH_DISTRIBUTED_H_
72 #define _FRSH_DISTRIBUTED_H_
74 #include "frsh_distributed_types.h"
75 #include "frsh_core_types.h"
78 * @defgroup distributed Distributed module
80 * This module defines the functions and typedefs for use in
81 * distributed applications.
83 * Each network is identified by its network_id and FRSH hides its
84 * characteristics completely. The type of network is implied with
85 * its ID via a configuration table defined at compile time.
87 * FRSH uses the "message" as the atomic unit for every exchange.
88 * Queue sizes are measured in number of pending messages.
90 * A message is composed of one or two packets of the underlying
91 * protocol. FRSH provides function calls to get the maximum number
92 * of packets in a message, the maximum number of bytes in a packet
93 * and the time required to send one packet. With this data the
94 * application can compute the budget (transmission time) that she
95 * needs and place it in a contract.
97 * Summary of typical steps.
99 * 1. Map (internally in FRSH implementation)
100 * - node--> node_addresses
101 * - network --> network_id's
102 * - unidirectional communication channel --> stream_id
103 * - other config --> protocol_info.
105 * 2. One of the nodes (which one is protocol-dependent) negotiates a
106 * "network contract" per communication channel that is used in
107 * the application. In each contract it is specified:
108 * - frsh_resource_type = FRSH_RT_NETWORK.
109 * - frsh_resource_id = <network id #>
110 * - budget: Time needed to send the require data per period.
111 * (you can use frsh_netinfo_*() functions for this).
112 * - period: Period of sendings.
113 * - Other protocol dependent function in protocol_contract_info.
115 * 3. In a sending node:
116 * 3.1. Create a send_endpoint per any unidirectional stream that will
118 * network_id --> the network through which the stream will
119 * flow (this is extra info needed for coherency
121 * destinator --> node_address of the receiver.
122 * stream_id --> the unidirectional communication channel.
123 * 3.2. Bind the send_endpoint to the network contract negotiated
125 * 3.3. The (processor) sending vres invokes frsh_send_(a)sync() to
126 * send the data through the corresponding stream.
128 * 4. In a receiving node:
129 * 4.1. Create a receive_endpoint per any unidirectional stream
130 * that will be used in receiving.
131 * 4.2. The processor expecting a reception of message invokes
132 * frsh_receive_(a)sync() to read the incoming data.
134 * 5. When all comunication is finished and the channel is no longer
135 * needed the nodes will destroy the send and receive endpoints
136 * and the network contract will be canceled.
139 #define FRSH_DISTRIBUTED_MODULE_SUPPORTED 1
141 //////////////////////////////////////////////////////////////////////
143 //////////////////////////////////////////////////////////////////////
146 * @defgroup distcontract Contract Info for Distributed Systems
147 * @ingroup distributed
149 * These functions help you calculate the needed budget for network
150 * contracts and also to include protocol dependent info in contract
157 * frsh_netinfo_get_packet_tx_time()
159 * This operation gives the transmission time that it takes to send a
160 * packet of the maximum size through the network designated by
161 * network_id, when there is no contention, but including any network
164 * It must be used by the application to calculate the minimum and
165 * maximum budgets used in the preparation of network contracts.
167 * The effective network utilization budget (usually called bandwidth)
168 * is always assigned as a number of packets per time unit, so the
169 * time used in the negotiation of contracts will be internally
170 * transformed into the corresponding necessary number of packets.
172 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
173 * identifier or if budget is a NULL pointer.
175 int frsh_netinfo_get_packet_tx_time
176 (frsh_resource_id_t network_id,
177 struct timespec *budget);
180 * frsh_netconfig_get_packet_size()
182 * This operation gives the maximum number of bytes that can be sent
183 * in a packet (MTU) through the network designated by network_id.
185 * It is usually a configuration value and it helps the user
186 * application to calculate the number of packets it will need to
187 * reserve for the periodic transmision of its messages and consequently
188 * prepare the corresponding contracts.
190 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
191 * identifier or if packet_size is a NULL pointer.
193 int frsh_netinfo_get_max_packet_size
194 (frsh_resource_id_t network_id,
195 size_t *packet_size);
198 * frsh_netconfig_get_max_packet_in_msg()
200 * This operation is used to obtain the maximum number of packets of
201 * which a message can be formed, for the specified network.
203 * A message is defined as the piece of information used in a send
204 * operation. Since the value returned by this operation is measured
205 * in packet units, the effective size can be calculated multiplying
206 * this value by the size of a packet.
208 * When the value returned by this operation is larger than 1 it means
209 * the implementation will make the partition of messages into packets
210 * and its recomposition at the receiving node.
212 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
213 * identifier or the pointer max_msg_size is NULL.
215 int frsh_netinfo_get_max_packet_in_msg
216 (frsh_resource_id_t network_id,
217 size_t *max_msg_size);
220 * frsh_contract_set_protocol_info
222 * We add protocol info to the contract
224 int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
225 frsh_contract_t *contract);
228 * frsh_contract_get_protocol_info
230 * We get protocol info from the contract
232 int frsh_contract_get_protocol_info(frsh_contract_t contract,
233 frsh_protocol_info_t *protocol_info);
239 //////////////////////////////////////////////////////////////////////
240 // TRANSMISSION SERVICES
241 //////////////////////////////////////////////////////////////////////
244 * @defgroup txservices Transmission services
245 * @ingroup distributed
247 * These functions allow to create and manage endpoints for sending
248 * and receiving and to perform send and receive operations both
249 * synchronously (blocking) and asynchronously (non-blocking).
256 * frsh_send_endpoint_create()
258 * This operation creates a unidirectional stream input endpoint
259 * through which, after the corresponding binding, it is possible to
260 * send data to a unicast or multicast receiver.
262 * @param[in] network_id Identifier of the network referred in the
263 * network contract as a resource_id.
264 * @param[in] receiver FRSH abstraction of the protocol address for the
266 * @param[in] stream_id Identifier of the communication channel between
267 * the nodes. Multiplexing is achieved by using
268 * different streams between the same nodes and the
270 * @param[in] queueing_info Queueing params of the endpoint (size and
272 * @param[in] protocol_info Optional protocol-dependent info.
273 * @param[out] endpoint Placeholder for the endpoint object.
275 int frsh_send_endpoint_create
276 (frsh_resource_id_t network_id,
277 frsh_node_address_t receiver,
278 frsh_stream_id_t stream_id,
279 frsh_endpoint_queueing_info_t queueing_info,
280 frsh_protocol_info_t protocol_info,
281 frsh_send_endpoint_t *endpoint);
284 * frsh_send_endpoint_get_params()
286 * This operation returns in the variables associated to the
287 * endpoint at creation time.
289 int frsh_send_endpoint_get_params
290 (const frsh_send_endpoint_t *endpoint,
291 frsh_resource_id_t *network_id,
292 frsh_node_address_t *receiver,
293 frsh_stream_id_t *stream,
294 frsh_endpoint_queueing_info_t *queueing_info,
295 frsh_protocol_info_t *protocol_info
299 * frsh_send_endpoint_destroy()
301 * This operation eliminates any resources reserved for the referenced
302 * endpoint. Pending messages will be discarded and processor-vres
303 * waiting in a synchronous operation will be awoken with an error
306 int frsh_send_endpoint_destroy
307 (frsh_send_endpoint_t *endpoint);
311 * frsh_send_endpoint_bind()
313 * This operation associates a send endpoint with a network vres,
314 * which means that messages sent through this endpoint will consume
315 * the vres's reserved bandwidth and its packets will be sent
316 * according to the contract established for that vres.
318 * If the endpoint is already bound to another vres, it is effectively
319 * unbound from it and bound to the specified one. However if a vres
320 * is already bound to another endpoint an error is returned.
322 * A consistency check is done in which the network_id specified at
323 * endpoint creation must correspond to the resource_id of the vres
326 * @return 0 if successful
327 * FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
329 * FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
330 * other send endpoint.
331 * FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
332 * as the one in the endpoint
334 int frsh_send_endpoint_bind
335 (frsh_vres_id_t vres,
336 frsh_send_endpoint_t *endpoint);
339 * frsh_send_endpoint_unbind()
341 * This operation unbinds a send endpoint from a vres. Endpoints with
342 * no vres associated cannot be used to send data, and they stay in
343 * that state until they are either eliminated or bound again.
345 * @return 0 if successful
346 * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
348 int frsh_send_endpoint_unbind
349 (frsh_send_endpoint_t *endpoint);
352 * frsh_endpoint_get_vres_id()
354 * This operation copies the id of the vres that is bound to the
355 * specified send endpoint into the variable pointed to by vres.
357 * @return 0 if successful
358 * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
359 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
362 int frsh_endpoint_get_vres_id
363 (const frsh_send_endpoint_t *endpoint,
364 frsh_vres_id_t *vres);
369 * This operation sends a message stored in msg and of length size
370 * through the given endpoint. The operation is non-blocking and
371 * returns immediately.
373 * An internal frsh service will schedule the sending of messages and
374 * implement the communications sporadic vres corresponding to the
375 * network vres bound to the given endpoint.
377 * Messages sent through the same endpoint are received in the same
378 * order in which they were sent.
380 * @returns 0 if successful
381 * FRSH_ERR_BAD_ARGUMENT if endpoint is not valid
382 * FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres
383 * FRSH_ERR_TOO_LARGE if the message is too large for the
385 * FRSH_ERR_BUFFER_FULL if the message has been discarded
386 * because the queue is full (and does not
387 * have the policy FRSH_QP_OLDEST.
390 (const frsh_send_endpoint_t *endpoint,
397 * Similar to previous function but now the sending vres gets blocked
398 * until the message is processed.
401 (const frsh_send_endpoint_t *endpoint,
408 * frsh_send_endpoint_get_status()
410 * This function tells the number of messages still pending in the
411 * endpoint queue together with some optional information which is
412 * protocol_dependent.
414 int frsh_send_endpoint_get_status(const frsh_send_endpoint_t *endpoint,
415 int *number_pending_msg,
416 frsh_protocol_info_t *protocol_info);
419 * frsh_receive_endpoint_create()
421 * This operation creates a receive endpoint associated with a
422 * undirectional stream within a network interface of the node.
424 * Receiving endpoints are not bound to any network vres, this is
425 * because don't originate any traffic.
427 * Note that the protocol address is not needed for reception because
428 * it can be determined internally by FRSH based on the network_id.
430 * Note also that messages may come from diferent originators.
432 * @param[in] network_id Id of the network from which we listen.
433 * @param[in] stream_id Id of the stream within the network.
434 * @param[in] queueing_info Buffering information(queue size and
436 * @param[in] protocol_info Extra protocol info opaque for the
438 * @param[in] endpoin Placeholder for the endpoint object.
440 * @return 0 if successful
441 * FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not valid.
443 int frsh_receive_endpoint_create
444 (frsh_resource_id_t network_id,
445 frsh_stream_id_t stream_id,
446 frsh_endpoint_queueing_info_t queueing_info,
447 frsh_protocol_info_t protocol_info,
448 frsh_receive_endpoint_t *endpoint);
452 * frsh_receive_endpoint_get_params()
454 * This operation returns in the variables associated to the
455 * endpoint at creation time.
457 int frsh_receive_endpoint_get_params
458 (frsh_resource_id_t *network_id,
459 frsh_stream_id_t *stream,
460 frsh_endpoint_queueing_info_t *queueing_info,
461 frsh_protocol_info_t *protocol_info,
462 const frsh_receive_endpoint_t *endpoint);
465 * frsh_receive_endpoint_destroy()
467 * This operation eliminates any resources reserved for the referenced
468 * endpoint. Pending messages will be discarded and processor-vres
469 * waiting in a synchronous operation will be awoken with an error
472 int frsh_receive_endpoint_destroy
473 (frsh_receive_endpoint_t *endpoint);
477 * frsh_receive_sync()
479 * If there are no messages available in the specified receive endpoint
480 * this operation blocks the calling thread waiting for a message to be
483 * When a message is available, if its size is less than or
484 * equal to the buffer_size, the function stores it in the variable
485 * pointed to by buffer and puts the number of bytes received in the
486 * variable pointed to by message size.
488 * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
489 * too small for the message received. In this case the message is
492 * Messages arriving at a receiver buffer that is full will be
493 * silently discarded (details in the queueing policy of the
494 * endpoint). The application is responsible of reading the receive
495 * endpoints with appropriate regularity, or of using a sequence
496 * number or some other mechanism to detect any lost messages.
498 * @return 0 if successful
499 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
500 * buffer or message_size are NULL.
501 * FRSH_ERR_NO_SPACE if the message size is bigger than the
504 int frsh_receive_sync
505 (const frsh_receive_endpoint_t *endpoint,
508 size_t *message_size);
513 * This operation is similar to the previous one but it works in a non
514 * blocking (asynchronous) fashion. If no message is available it
515 * returns with error FRSH_NO_MESSAGE.
517 * @return 0 if successful
518 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
519 * buffer or message_size are NULL.
520 * FRSH_NO_MESSAGE if no messages are available in the queue.
521 * FRSH_ERR_NO_SPACE if the message size is bigger than the
525 (const frsh_receive_endpoint_t *endpoint,
528 size_t *message_size);
532 * frsh_receive_endpoint_get_status
534 * This function tells the number of messages still pending in the
535 * endpoint queue together with some optional information which is
536 * protocol_dependent.
538 int frsh_send_endpoint_get_status(const frsh_receive_endpoint_t *endpoint,
539 int *number_pending_messages,
540 frsh_protocol_info_t *protocol_info);
547 #endif // _FRSH_DISTRIBUTED_H_