]> rtime.felk.cvut.cz Git - frescor/frsh-include.git/blob - frsh_distributed.h
c23fd7efe9888879782625cb07e51e79cdf0ee7b
[frescor/frsh-include.git] / frsh_distributed.h
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 FRESCOR consortium partners:
3 //
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
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
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
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //  This file is part of FRSH API
35 //
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)
39 //  any later version.
40 //
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.
45 //
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
49 //  02111-1307, USA.
50 //
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
56 //  Public License.
57 // -----------------------------------------------------------------------
58 //frsh_distributed.h
59 //==============================================
60 //  ******** *******    ********  **      **
61 //  **///// /**////**  **//////  /**     /**
62 //  **      /**   /** /**        /**     /**
63 //  ******* /*******  /********* /**********
64 //  **////  /**///**  ////////** /**//////**
65 //  **      /**  //**        /** /**     /**
66 //  **      /**   //** ********  /**     /**
67 //  //       //     // ////////   //      //
68 //
69 // FRSH(FRescor ScHeduler), pronounced "fresh"
70 //==============================================
71 #ifndef _FRSH_DISTRIBUTED_H_
72 #define _FRSH_DISTRIBUTED_H_
73
74
75 /**
76  * @file frsh_distributed.h
77  **/
78
79
80 #include "frsh_distributed_types.h"
81 #include "frsh_core_types.h"
82
83 /**
84  * @defgroup distributed Distributed module
85  *
86  * This module defines the functions and typedefs for use in
87  * distributed applications.
88  *
89  * Each network is identified by its network_id and FRSH hides its
90  * characteristics completely.  The type of network is implied with
91  * its ID via a configuration table defined at compile time.
92  *
93  * FRSH uses the "message" as the atomic unit for every exchange.
94  * Queue sizes are measured in number of pending messages.
95  *
96  * FRSH provides a function to calculate the transmision time needed
97  * for a certain message size in a network as well as the maximum
98  * message size that can admit.
99  *
100  * Note also that package delivery guarantee is protocol dependent.
101  * For protocols in which the order is no guaranteed, the application
102  * needs to add extra info to detect possible package disorder.
103  *
104  * Summary of typical steps.
105  *
106  * 1.  Map (internally in FRSH implementation)
107  *     -   node--> network_addresses
108  *     -   network --> network_id's
109  *     -   unidirectional communication channel --> stream_id
110  *     -   other config --> protocol_info.
111  *
112  * 2.  In a sending node:
113  *     2.1. Negotiates a "network contract" per communication channel
114  *          that is used in the application.  In the contract it is
115  *          specified:
116  *          -  frsh_resource_type = FRSH_RT_NETWORK.
117  *          -  frsh_resource_id = <network id #>
118  *          -  budget:  Time needed to send the required data per period.
119  *                 (you can use frsh_netinfo_*() functions for this).
120  *          -  period:  Period of sendings.
121  *          -  Queueing info:  How will sends be queued at sendEndpoint.
122  *          -  Other protocol dependent function in protocol_contract_info.
123  *     2.2. Create a send_endpoint per any unidirectional stream that will
124  *          be used in sending
125  *          network_id --> the network through which the stream will
126  *                       flow (this is extra info needed for coherency
127  *                       with the bind).
128  *          destinator --> network_address of the destination.
129  *          stream_id --> the unidirectional communication channel.
130  *     2.3. Bind the send_endpoint to the network contract negotiated
131  *          above.
132  *     2.4. The (processor) sending vres invokes frsh_send_(a)sync() to
133  *          send the data through the corresponding stream.
134  *
135  * 3.  In a receiving node:
136  *     3.1. Create a receive_endpoint per any unidirectional stream
137  *          that will be used in receiving.
138  *     3.2. The processor expecting a reception of message invokes
139  *          frsh_receive_(a)sync() to read the incoming data.
140  *
141  * 4.  When all comunication is finished and the channel is no longer
142  *     needed the nodes will destroy the send and receive endpoints
143  *     and the network contract will be canceled.
144  **/
145
146
147 #define FRSH_DISTRIBUTED_MODULE_SUPPORTED       1
148
149 //////////////////////////////////////////////////////////////////////
150 //           CONTRACT ASPECTS
151 //////////////////////////////////////////////////////////////////////
152
153 /**
154  * @defgroup distcontract Contract Info for Distributed Systems
155  * @ingroup distributed
156  *
157  * These functions help you calculate the needed budget for network
158  * contracts and also to include protocol dependent info in contract
159  * parameters.
160  *
161  * @{
162  **/
163
164 /**
165  * frsh_network_get_max_message_size()
166  *
167  * This operation gives the maximum number of bytes that can be sent
168  * at a time through the send function when using the network designated by
169  * 'resource_id' and sending it to 'destination'.
170  *
171  * If the application needs to send bigger messages it will have to
172  * split them.
173  *
174  * Some protocols, like IP, are capable of sending large messages
175  * (and use fragmentation internally) but other protocols don't.
176  *
177  * @param[in] resource_id The network we want the tx time from.
178  * @param[in] destination The destination address
179  * @param[out] max_size The maximum number of bytes for each message
180  *
181  * @return
182  *   FRSH_NO_ERROR \n
183  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
184  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
185  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
186  *   a network accessible from the current processing node \n
187  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
188  *   invalid \n
189  *
190  **/
191 int frsh_network_get_max_message_size
192    (const frsh_resource_id_t resource_id,
193     const frsh_network_address_t destination,
194     size_t *max_size);
195
196 /**
197  * frsh_network_bytes_to_budget()
198  *
199  * This operation converts a number of bytes into a temporal budget for
200  * a specific network. Network overheads are not included here but are
201  * considered internally when negotiating a specific contract.
202  *
203  * @param[in] resource_id The network
204  * @param[in] nbytes Number of bytes
205  * @param[out] budget The network budget for nbytes
206  *
207  * @return
208  *   FRSH_NO_ERROR \n
209  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
210  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
211  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
212  *   a network accessible from the current processing node \n
213  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
214  *   than zero \n
215  *
216  **/
217 int frsh_network_bytes_to_budget
218    (const frsh_resource_id_t resource_id,
219     const size_t nbytes,
220     struct timespec *budget);
221
222 /**
223  * frsh_network_budget_to_bytes()
224  *
225  * This operation converts a temporal budget into a number of bytes for
226  * a specific network. Network overheads are not included.
227  *
228  * @param[in] resource_id The network
229  * @param[in] budget The network budget for nbytes
230  * @param[out] nbytes Number of bytes
231  *
232  * @return
233  *   FRSH_NO_ERROR \n
234  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
235  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
236  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
237  *   a network accessible from the current processing node \n
238  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
239  *   an invalid time value \n
240  *
241  **/
242 int frsh_network_budget_to_bytes
243    (const frsh_resource_id_t resource_id,
244     const struct timespec *budget,
245     size_t *nbytes);
246
247 /**
248  * frsh_network_get_min_effective_budget()
249  *
250  * This operation gets the minimum effective budget for a network. Each message
251  * consumes a contracted budget in "chunks" (i.e: packets) that we call
252  * minimum effective budget.
253  *
254  * A negotiated contract, for N bytes in a period T, means that there is a
255  * virtual resource that reserves for the user:
256  *
257  *   Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
258  *
259  * Note that if the user decides not to send these N bytes at once but, say,
260  * one byte at a time, it will consume one "CHUNK" at a time and the reserved
261  * budget will become exhausted before sending all the bytes.
262  *
263  * @param[in] resource_id The network
264  * @param[out] budget The network budget
265  *
266  * @return
267  *   FRSH_NO_ERROR \n
268  *   FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
269  *   FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
270  *   FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
271  *   a network accessible from the current processing node \n
272  *   FRSH_ERR_BAD_ARGUMENT: if pointers are NULL \n
273  *
274  **/
275 int frsh_network_get_min_effective_budget
276    (const frsh_resource_id_t resource_id,
277     struct timespec *budget);
278
279 /**
280  * frsh_contract_set_queueing_info()
281  *
282  * This function adds queueing parameters that will be used in the
283  * sendEndpoint when the sendEndpoint is bound to the vres.
284  **/
285 int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
286                                     frsh_contract_t *contract);
287
288 /**
289  * frsh_contract_get_queueing_info()
290  *
291  * This function gets the queueing parameters that were specified in
292  * the network contract.
293  **/
294 int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
295                                     frsh_endpoint_queueing_info_t *queueing_info);
296
297 /**
298  * frsh_contract_set_protocol_info
299  *
300  * We add protocol info to the contract
301  **/
302 int frsh_contract_set_protocol_info(frsh_protocol_info_t protocol_info,
303                                     frsh_contract_t *contract);
304
305 /**
306  * frsh_contract_get_protocol_info
307  *
308  * We get protocol info from the contract
309  **/
310 int frsh_contract_get_protocol_info(frsh_contract_t contract,
311                                     frsh_protocol_info_t *protocol_info);
312
313 /*@}*/
314
315 //////////////////////////////////////////////////////////////////////
316 //           TRANSMISSION SERVICES
317 //////////////////////////////////////////////////////////////////////
318
319 /**
320  * @defgroup txservices Transmission services
321  * @ingroup distributed
322  *
323  * These functions allow to create and manage endpoints for sending
324  * and receiving and to perform send and receive operations both
325  * synchronously (blocking) and asynchronously (non-blocking).
326  *
327  * @{
328  **/
329
330
331 /**
332  * frsh_send_endpoint_create()
333  *
334  * This operation creates a unidirectional stream input endpoint
335  * through which, after the corresponding binding, it is possible to
336  * send data to a unicast or multicast destination.
337  *
338  * @param[in] network_id  Identifier of the network referred in the
339  *                        network contract as a resource_id.
340  * @param[in] destination    FRSH abstraction of the protocol address for the
341  *                        destinator node.
342  * @param[in] stream_id   Identifier of the communication channel between
343  *                        the nodes.  Multiplexing is achieved by using
344  *                        different streams between the same nodes and the
345  *                        same network.
346  * @param[in] queueing_info Queueing params of the endpoint (size and
347  *                           policy).
348  * @param[in] protocol_info Optional protocol-dependent info.
349  * @param[out] endpoint   Placeholder for the endpoint object.
350  **/
351 int frsh_send_endpoint_create
352   (frsh_resource_id_t     network_id,
353    frsh_network_address_t    destination,
354    frsh_stream_id_t       stream_id,
355    frsh_send_endpoint_protocol_info_t protocol_info,
356    frsh_send_endpoint_t  *endpoint);
357
358 /**
359  * frsh_send_endpoint_get_params()
360  *
361  * This operation returns in the variables associated to the
362  * endpoint at creation time.
363  **/
364 int frsh_send_endpoint_get_params
365     (const frsh_send_endpoint_t  *endpoint,
366      frsh_resource_id_t        *network_id,
367      frsh_network_address_t       *destination,
368      frsh_stream_id_t          *stream,
369      frsh_send_endpoint_protocol_info_t  *protocol_info);
370
371 /**
372  * frsh_send_endpoint_destroy()
373  *
374  * This operation eliminates any resources reserved for the referenced
375  * endpoint.  Pending messages will be discarded and processor-vres
376  * waiting in a synchronous operation will be awoken with an error
377  * code.
378  **/
379 int frsh_send_endpoint_destroy
380      (frsh_send_endpoint_t  *endpoint);
381
382
383 /**
384  * frsh_send_endpoint_bind()
385  *
386  * This operation associates a send endpoint with a network vres,
387  * which means that messages sent through this endpoint will consume
388  * the vres's reserved bandwidth and its packets will be sent
389  * according to the contract established for that vres.
390  *
391  * If the endpoint is already bound to another vres, it is effectively
392  * unbound from it and bound to the specified one.  However if a vres
393  * is already bound to another endpoint an error is returned.
394  *
395  * A consistency check is done in which the network_id specified at
396  * endpoint creation must correspond to the resource_id of the vres
397  * contract.
398  *
399  * @return  0 if successful \n
400  *      FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
401  *                            valid \n
402  *      FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
403  *                               other send endpoint \n
404  *      FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
405  *                               as the one in the endpoint \n
406  **/
407 int frsh_send_endpoint_bind
408   (frsh_vres_id_t      vres,
409    frsh_send_endpoint_t  *endpoint);
410
411 /**
412  * frsh_send_endpoint_unbind()
413  *
414  * This operation unbinds a send endpoint from a vres. Endpoints with
415  * no vres associated cannot be used to send data, and they stay in
416  * that state  until they are either eliminated or bound again.
417  *
418  * @return 0 if successful \n
419  *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
420  **/
421 int frsh_send_endpoint_unbind
422   (frsh_send_endpoint_t  *endpoint);
423
424 /**
425  * frsh_send_endpoint_get_vres_id()
426  *
427  * This operation copies the id of the vres that is bound to the
428  * specified send endpoint into the variable pointed to by vres.
429  *
430  * @return 0 if successful \n
431  *         FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
432  *         FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
433  *                               is NULL \n
434  **/
435 int frsh_send_endpoint_get_vres_id
436   (const frsh_send_endpoint_t  *endpoint,
437    frsh_vres_id_t            *vres);
438
439 /**
440  * frsh_send_async()
441  *
442  * This operation sends a message stored in msg and of length size
443  * through the given endpoint. The operation is non-blocking and
444  * returns immediately.
445  *
446  * An internal frsh service will schedule the sending of messages and
447  * implement the communications sporadic vres  corresponding to the
448  * network vres bound to the given endpoint.
449  *
450  * @returns 0 if successful \n
451  *       FRSH_ERR_BAD_ARGUMENT if endpoint is not valid \n
452  *       FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres \n
453  *       FRSH_ERR_TOO_LARGE if the message is too large for the
454  *                             network protocol \n
455  *       FRSH_ERR_BUFFER_FULL if the message has been discarded
456  *                            because the queue is full (and does not
457  *                            have the policy FRSH_QP_OLDEST \n
458  **/
459 int frsh_send_async
460   (const frsh_send_endpoint_t  *endpoint,
461    void                       *msg,
462    size_t                      size);
463
464 /**
465  * frsh_send_sync()
466  *
467  * Similar to previous function but now the sending vres gets blocked
468  * until the message is processed.
469  **/
470 int frsh_send_sync
471   (const frsh_send_endpoint_t *endpoint,
472    void                       *msg,
473    size_t                      size);
474
475 /**
476  * frsh_send_endpoint_get_status()
477  *
478  * This function tells the number of messages still pending in the
479  * endpoint queue, whether the network is up or down with some
480  * optional information which is protocol_dependent.
481  **/
482 int frsh_send_endpoint_get_status(const frsh_send_endpoint_t *endpoint,
483                                   int *number_pending_msg,
484                                   frsh_endpoint_network_status *network_status,
485                                   frsh_protocol_status_t *protocol_status);
486
487 /**
488  * frsh_receive_endpoint_create()
489  *
490  * This operation creates a receive endpoint associated with a
491  * undirectional stream within a network interface of the node.
492  *
493  * Receiving endpoints are not bound to any network vres, this is
494  * because don't originate any traffic.
495  *
496  * Note that the protocol address is not needed for reception because
497  * it can be determined internally by FRSH based on the network_id.
498  *
499  * Note also that messages may come from diferent originators.
500  *
501  * @param[in] network_id  Id of the network from which we listen.
502  * @param[in] stream_id  Id of the stream within the network.
503  * @param[in] queueing_info Buffering information(queue size and
504  *                          policy).
505  * @param[in] protocol_info Extra protocol info opaque for the
506  *                          application.
507  * @param[in] endpoin  Placeholder for the endpoint object.
508  *
509  * @return 0 if successful \n
510  *   FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not
511  *      valid \n
512  **/
513 int frsh_receive_endpoint_create
514   (frsh_resource_id_t        network_id,
515    frsh_stream_id_t          stream_id,
516    frsh_endpoint_queueing_info_t queueing_info,
517    frsh_receive_endpoint_protocol_info_t protocol_info,
518    frsh_receive_endpoint_t  *endpoint);
519
520 /**
521  * frsh_receive_endpoint_get_params()
522  *
523  * This operation returns in the variables associated to the
524  * endpoint at creation time.
525  **/
526 int frsh_receive_endpoint_get_params
527      (const frsh_receive_endpoint_t  *endpoint,
528      frsh_resource_id_t        *network_id,
529      frsh_stream_id_t          *stream,
530      frsh_endpoint_queueing_info_t   *queueing_info,
531      frsh_receive_endpoint_protocol_info_t   *protocol_info);
532
533 /**
534  * frsh_receive_endpoint_destroy()
535  *
536  * This operation eliminates any resources reserved for the referenced
537  * endpoint.  Pending messages will be discarded and processor-vres
538  * waiting in a synchronous operation will be awoken with an error
539  * code.
540  **/
541 int frsh_receive_endpoint_destroy
542      (frsh_receive_endpoint_t  *endpoint);
543
544
545 /**
546  * frsh_receive_sync()
547  *
548  * If there are no messages available in the specified receive endpoint
549  * this operation blocks the calling thread waiting for a message to be
550  * received.
551  *
552  * When a message is available, if its size is less than or
553  * equal to the buffer_size, the function stores it in the variable
554  * pointed to by buffer and puts the number of bytes received in the
555  * variable pointed to by message size.
556  *
557  * The function fails with FRSH_ERR_NO_SPACE if the buffersize is
558  * too small for the message received.  In this case the message is
559  * lost.
560  *
561  * Messages arriving at a destination buffer that is full will be
562  * silently discarded (details in the queueing policy of the
563  * endpoint). The application is responsible of reading the receive
564  * endpoints with appropriate regularity, or of using a sequence
565  * number or some other mechanism to detect any lost messages.
566  *
567  * @return 0 if successful \n
568  *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
569  *       buffer or message_size are NULL.\n
570  *     FRSH_ERR_NO_SPACE if the message size is bigger than the
571  *       provided buffer \n
572  **/
573 int frsh_receive_sync
574   (const frsh_receive_endpoint_t  *endpoint,
575    void                          *buffer,
576    size_t                         buffer_size,
577    size_t                        *message_size,
578    frsh_network_address_t *from);
579
580 /**
581  * frsh_receive_async()
582  *
583  * This operation is similar to the previous one but it works in a non
584  * blocking (asynchronous) fashion.  If no message is available it
585  * returns with error FRSH_NO_MESSAGE.
586  *
587  * @return 0 if successful \n
588  *     FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
589  *       buffer or message_size are NULL \n
590  *     FRSH_NO_MESSAGE if no messages are available in the queue \n
591  *     FRSH_ERR_NO_SPACE if the message size is bigger than the
592  *       provided buffer \n
593  **/
594 int frsh_receive_async
595   (const frsh_receive_endpoint_t  *endpoint,
596    void                          *buffer,
597    size_t                         buffer_size,
598    size_t                        *message_size,
599    frsh_network_address_t *from);
600
601
602 /**
603  * frsh_receive_endpoint_get_status
604  *
605  * This function tells the number of messages still pending in the
606  * endpoint queue, whether the network is up or down and some optional
607  * information which is protocol dependent.
608  **/
609 int frsh_receive_endpoint_get_status(const frsh_receive_endpoint_t *endpoint,
610                                   int *number_pending_messages,
611                                   frsh_endpoint_network_status *network_status,
612                                   frsh_protocol_status_t *protocol_status);
613
614
615
616 /*@}*/
617
618
619 #endif // _FRSH_DISTRIBUTED_H_