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 * Summary of typical steps.
89 * 1. Map (internally in FRSH implementation)
90 * - node--> node_addresses
91 * - network --> network_id's
92 * - unidirectional communication channel --> stream_id
93 * - other config --> protocol_info.
95 * 2. One of the nodes (which one is protocol-dependent) negotiates a
96 * "network contract" per communication channel that is used in
97 * the application. In each contract it is specified:
98 * - frsh_resource_type = FRSH_RT_NETWORK.
99 * - frsh_resource_id = <network id #>
100 * - budget: Time needed to send the require data per period.
101 * (you can use frsh_netinfo_*() functions for this).
102 * - period: Period of sendings.
103 * - Other protocol dependent function in protocol_contract_info.
105 * 3. In a sending node:
106 * 3.1. Create a send_endpoint per any unidirectional stream that will
108 * network_id --> the network through which the stream will
109 * flow (this is extra info needed for coherency
111 * destinator --> node_address of the receiver.
112 * stream_id --> the unidirectional communication channel.
113 * 3.2. Bind the send_endpoint to the network contract negotiated
115 * 3.3. The (processor) sending vres invokes frsh_send_(a)sync() to
116 * send the data through the corresponding stream.
118 * 4. In a receiving node:
119 * 4.1. Create a receive_endpoint per any unidirectional stream
120 * that will be used in receiving.
121 * 4.2. The processor expecting a reception of message invokes
122 * frsh_receive_(a)sync() to read the incoming data.
124 * 5. When all comunication is finished and the channel is no longer
125 * needed the nodes will destroy the send and receive endpoints
126 * and the network contract will be canceled.
129 #define FRSH_DISTRIBUTED_MODULE_SUPPORTED 1
131 //////////////////////////////////////////////////////////////////////
133 //////////////////////////////////////////////////////////////////////
136 * @defgroup distcontract Contract Info for Distributed Systems
137 * @ingroup distributed
139 * These functions help you calculate the needed budget for network
140 * contracts and also to include protocol dependent info in contract
147 * frsh_netinfo_get_packet_tx_time()
149 * This operation gives the transmission time that it takes to send a
150 * packet of the maximum size through the network designated by
151 * network_id, when there is no contention, but including any network
154 * It must be used by the application to calculate the minimum and
155 * maximum budgets used in the preparation of network contracts.
157 * The effective network utilization budget (usually called bandwidth)
158 * is always assigned as a number of packets per time unit, so the
159 * time used in the negotiation of contracts will be internally
160 * transformed into the corresponding necessary number of packets.
162 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
163 * identifier or if budget is a NULL pointer.
165 int frsh_netinfo_get_packet_tx_time
166 (frsh_resource_id_t network_id,
167 struct timespec *budget);
170 * frsh_netconfig_get_packet_size()
172 * This operation gives the maximum number of bytes that can be sent
173 * in a packet (MTU) through the network designated by network_id.
175 * It is usually a configuration value and it helps the user
176 * application to calculate the number of packets it will need to
177 * reserve for the periodic transmision of its messages and consequently
178 * prepare the corresponding contracts.
180 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
181 * identifier or if packet_size is a NULL pointer.
183 int frsh_netinfo_get_max_packet_size
184 (frsh_resource_id_t network_id,
185 size_t *packet_size);
188 * frsh_netconfig_get_max_packet_in_msg()
190 * This operation is used to obtain the maximum number of packets of
191 * which a message can be formed, for the specified network.
193 * A message is defined as the piece of information used in a send
194 * operation. Since the value returned by this operation is measured
195 * in packet units, the effective size can be calculated multiplying
196 * this value by the size of a packet.
198 * When the value returned by this operation is larger than 1 it means
199 * the implementation will make the partition of messages into packets
200 * and its recomposition at the receiving node.
202 * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
203 * identifier or the pointer max_msg_size is NULL.
205 int frsh_netinfo_get_max_packet_in_msg
206 (frsh_resource_id_t network_id,
207 size_t *max_msg_size);
210 * frsh_contract_set_protocol_info
212 * We add protocol info to the contract
214 int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
215 frsh_contract_t *contract);
218 * frsh_contract_get_protocol_info
220 * We get protocol info from the contract
222 int frsh_contract_get_protocol_info(frsh_contract_t contract,
223 frsh_protocol_info_t *protocol_info);
229 //////////////////////////////////////////////////////////////////////
230 // TRANSMISSION SERVICES
231 //////////////////////////////////////////////////////////////////////
234 * @defgroup txservices Transmission services
235 * @ingroup distributed
237 * These functions allow to create and manage endpoints for sending
238 * and receiving and to perform send and receive operations both
239 * synchronously (blocking) and asynchronously (non-blocking).
246 * frsh_send_endpoint_create()
248 * This operation creates a unidirectional stream input endpoint
249 * through which, after the corresponding binding, it is possible to
250 * send data to a unicast or multicast receiver.
252 * @param[in] network_id Identifier of the network referred in the
253 * network contract as a resource_id.
254 * @param[in] receiver FRSH abstraction of the protocol address for the
256 * @param[in] stream_id Identifier of the communication channel between
257 * the nodes. Multiplexing is achieved by using
258 * different streams between the same nodes and the
260 * @param[in] queueing_info Queueing params of the endpoint (size and
262 * @param[in] protocol_info Optional protocol-dependent info.
263 * @param[out] endpoint Placeholder for the endpoint object.
265 int frsh_send_endpoint_create
266 (frsh_resource_id_t network_id,
267 frsh_node_address_t receiver,
268 frsh_stream_id_t stream_id,
269 frsh_endpoint_queueing_info_t queueing_info,
270 frsh_protocol_info_t protocol_info,
271 frsh_send_endpoint_t *endpoint);
274 * frsh_send_endpoint_get_params()
276 * This operation returns in the variables associated to the
277 * endpoint at creation time.
279 int frsh_send_endpoint_get_params
280 (const frsh_send_endpoint_t *endpoint,
281 frsh_resource_id_t *network_id,
282 frsh_node_address_t *receiver,
283 frsh_stream_id_t *stream,
284 frsh_endpoint_queueing_info_t *queueing_info,
285 frsh_protocol_info_t *protocol_info
289 * frsh_send_endpoint_destroy()
291 * This operation eliminates any resources reserved for the referenced
292 * endpoint. Pending messages will be discarded and processor-vres
293 * waiting in a synchronous operation will be awoken with an error
296 int frsh_send_endpoint_destroy
297 (frsh_send_endpoint_t *endpoint);
301 * frsh_send_endpoint_bind()
303 * This operation associates a send endpoint with a network vres,
304 * which means that messages sent through this endpoint will consume
305 * the vres's reserved bandwidth and its packets will be sent
306 * according to the contract established for that vres.
308 * If the endpoint is already bound to another vres, it is effectively
309 * unbound from it and bound to the specified one. However if a vres
310 * is already bound to another endpoint an error is returned.
312 * A consistency check is done in which the network_id specified at
313 * endpoint creation must correspond to the resource_id of the vres
316 * @return 0 if successful
317 * FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
319 * FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
320 * other send endpoint.
321 * FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
322 * as the one in the endpoint
324 int frsh_send_endpoint_bind
325 (frsh_vres_id_t vres,
326 frsh_send_endpoint_t *endpoint);
329 * frsh_send_endpoint_unbind()
331 * This operation unbinds a send endpoint from a vres. Endpoints with
332 * no vres associated cannot be used to send data, and they stay in
333 * that state until they are either eliminated or bound again.
335 * @return 0 if successful
336 * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
338 int frsh_send_endpoint_unbind
339 (frsh_send_endpoint_t *endpoint);
342 * frsh_endpoint_get_vres_id()
344 * This operation copies the id of the vres that is bound to the
345 * specified send endpoint into the variable pointed to by vres.
347 * @return 0 if successful
348 * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
349 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
352 int frsh_endpoint_get_vres_id
353 (const frsh_send_endpoint_t *endpoint,
354 frsh_vres_id_t *vres);
359 * This operation sends a message stored in msg and of length size
360 * through the given endpoint. The operation is non-blocking and
361 * returns immediately.
363 * An internal frsh service will schedule the sending of messages and
364 * implement the communications sporadic vres corresponding to the
365 * network vres bound to the given endpoint.
367 * Messages sent through the same endpoint are received in the same
368 * order in which they were sent.
370 * @returns 0 if successful
371 * FRSH_ERR_BAD_ARGUMENT if endpoint is not valid
372 * FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres
373 * FRSH_ERR_TOO_LARGE if the message is too large for the
375 * FRSH_ERR_BUFFER_FULL if the message has been discarded
376 * because the queue is full (and does not
377 * have the policy FRSH_QP_OLDEST.
380 (const frsh_send_endpoint_t *endpoint,
387 * Similar to previous function but now the sending vres gets blocked
388 * until the message is processed.
391 (const frsh_send_endpoint_t *endpoint,
398 * frsh_send_endpoint_get_status()
400 * This function tells the number of messages still pending in the
401 * endpoint queue together with some optional information which is
402 * protocol_dependent.
404 int frsh_send_endpoint_get_status(const frsh_send_endpoint_t *endpoint,
405 int *number_pending_msg,
406 frsh_protocol_info_t *protocol_info);
409 * frsh_receive_endpoint_create()
411 * This operation creates a receive endpoint associated with a
412 * undirectional stream within a network interface of the node.
414 * Receiving endpoints are not bound to any network vres, this is
415 * because don't originate any traffic.
417 * Note that the protocol address is not needed for reception because
418 * it can be determined internally by FRSH based on the network_id.
420 * Note also that messages may come from diferent originators.
422 * @param[in] network_id Id of the network from which we listen.
423 * @param[in] stream_id Id of the stream within the network.
424 * @param[in] queueing_info Buffering information(queue size and
426 * @param[in] protocol_info Extra protocol info opaque for the
428 * @param[in] endpoin Placeholder for the endpoint object.
430 * @return 0 if successful
431 * FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not valid.
433 int frsh_receive_endpoint_create
434 (frsh_resource_id_t network_id,
435 frsh_stream_id_t stream_id,
436 frsh_endpoint_queueing_info_t queueing_info,
437 frsh_protocol_info_t protocol_info,
438 frsh_receive_endpoint_t *endpoint);
442 * frsh_receive_endpoint_get_params()
444 * This operation returns in the variables associated to the
445 * endpoint at creation time.
447 int frsh_receive_endpoint_get_params
448 (frsh_resource_id_t *network_id,
449 frsh_stream_id_t *stream,
450 frsh_endpoint_queueing_info_t *queueing_info,
451 frsh_protocol_info_t *protocol_info,
452 const frsh_receive_endpoint_t *endpoint);
455 * frsh_receive_endpoint_destroy()
457 * This operation eliminates any resources reserved for the referenced
458 * endpoint. Pending messages will be discarded and processor-vres
459 * waiting in a synchronous operation will be awoken with an error
462 int frsh_receive_endpoint_destroy
463 (frsh_receive_endpoint_t *endpoint);
467 * frsh_receive_sync()
469 * If there are no messages available in the specified receive endpoint
470 * this operation blocks the calling thread waiting for a message to be
473 * When a message is available, if its size is less than or
474 * equal to the buffer_size, the function stores it in the variable
475 * pointed to by buffer and puts the number of bytes received in the
476 * variable pointed to by message size.
478 * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
479 * too small for the message received. In this case the message is
482 * Messages arriving at a receiver buffer that is full will be
483 * silently discarded (details in the queueing policy of the
484 * endpoint). The application is responsible of reading the receive
485 * endpoints with appropriate regularity, or of using a sequence
486 * number or some other mechanism to detect any lost messages.
488 * @return 0 if successful
489 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
490 * buffer or message_size are NULL.
491 * FRSH_ERR_NO_SPACE if the message size is bigger than the
494 int frsh_receive_sync
495 (const frsh_receive_endpoint_t *endpoint,
498 size_t *message_size);
503 * This operation is similar to the previous one but it works in a non
504 * blocking (asynchronous) fashion. If no message is available it
505 * returns with error FRSH_NO_MESSAGE.
507 * @return 0 if successful
508 * FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
509 * buffer or message_size are NULL.
510 * FRSH_NO_MESSAGE if no messages are available in the queue.
511 * FRSH_ERR_NO_SPACE if the message size is bigger than the
515 (const frsh_receive_endpoint_t *endpoint,
518 size_t *message_size);
522 * frsh_receive_endpoint_get_status
524 * This function tells the number of messages still pending in the
525 * endpoint queue together with some optional information which is
526 * protocol_dependent.
528 int frsh_send_endpoint_get_status(const frsh_receive_endpoint_t *endpoint,
529 int *number_pending_messages,
530 frsh_protocol_info_t *protocol_info);
537 #endif // _FRSH_DISTRIBUTED_H_