1 /**************************************************************************/
2 /* ---------------------------------------------------------------------- */
3 /* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
5 /* Universidad de Cantabria, SPAIN */
6 /* University of York, UK */
7 /* Scuola Superiore Sant'Anna, ITALY */
8 /* Kaiserslautern University, GERMANY */
9 /* Univ. Politécnica Valencia, SPAIN */
10 /* Czech Technical University in Prague, CZECH REPUBLIC */
12 /* Thales Communication S.A. FRANCE */
13 /* Visual Tools S.A. SPAIN */
14 /* Rapita Systems Ltd UK */
17 /* See http://www.frescor.org for a link to partners' websites */
19 /* FRESCOR project (FP6/2005/IST/5-034026) is funded */
20 /* in part by the European Union Sixth Framework Programme */
21 /* The European Union is not liable of any use that may be */
22 /* made of this code. */
25 /* This file is part of FRSH (FRescor ScHeduler) */
27 /* FRSH is free software; you can redistribute it and/or modify it */
28 /* under terms of the GNU General Public License as published by the */
29 /* Free Software Foundation; either version 2, or (at your option) any */
30 /* later version. FRSH is distributed in the hope that it will be */
31 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
32 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
33 /* General Public License for more details. You should have received a */
34 /* copy of the GNU General Public License along with FRSH; see file */
35 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
36 /* Cambridge, MA 02139, USA. */
38 /* As a special exception, including FRSH header files in a file, */
39 /* instantiating FRSH generics or templates, or linking other files */
40 /* with FRSH objects to produce an executable application, does not */
41 /* by itself cause the resulting executable application to be covered */
42 /* by the GNU General Public License. This exception does not */
43 /* however invalidate any other reasons why the executable file might be */
44 /* covered by the GNU Public License. */
45 /**************************************************************************/
48 * @file frsh_contract.c
49 * @author Michal Sojka <sojkam1@fel.cvut.cz>
50 * Dario Faggioli <faggioli@gandalf.sssup.it>
52 * @brief Implementation of FRSH contract API on top of FRES contracts.
56 #include <fres_contract.h>
57 #include <fres_contract_idl.h>
58 #include <frsh_core.h>
59 #include <frsh_error.h>
60 #include <fres_blocks.h>
63 #include "frsh_forb.h"
64 #include <fra_generic.h>
66 /**********************************/
67 /* -----===== FRSH API =====----- */
68 /**********************************/
71 frsh_contract_init(frsh_contract_t *contract)
73 frsh_rel_time_t zero_msec = fosa_msec_to_rel_time(0);
74 if (!contract) return FRSH_ERR_BAD_ARGUMENT;
76 *contract = fres_contract_new();
77 if (!(*contract)) goto err;
79 /* Set default parameters */
80 frsh_contract_set_resource_and_label(contract,
84 frsh_contract_set_basic_params(contract,
87 FRSH_WT_INDETERMINATE,
94 int frsh_contract_set_basic_params
95 (frsh_contract_t *contract,
96 const frsh_rel_time_t *budget_min,
97 const frsh_rel_time_t *period_max,
98 const frsh_workload_t workload,
99 const frsh_contract_type_t contract_type)
107 return FRSH_ERR_BAD_ARGUMENT;
110 if ((fosa_rel_time_is_null(*period_max) &&
111 !fosa_rel_time_is_null(*budget_min)) ||
112 (!fosa_rel_time_is_null(*period_max) &&
113 fosa_rel_time_is_null(*budget_min)) ||
114 fosa_rel_time_smaller(*period_max, *budget_min))
115 return FRSH_ERR_BAD_ARGUMENT;
117 if (workload != FRSH_WT_BOUNDED &&
118 workload != FRSH_WT_INDETERMINATE)
119 return FRSH_ERR_BAD_ARGUMENT;
121 if (contract_type != FRSH_CT_REGULAR &&
122 workload != FRSH_CT_BACKGROUND &&
123 workload != FRSH_CT_DUMMY)
124 return FRSH_ERR_BAD_ARGUMENT;
126 b = malloc(sizeof(*b));
127 if (!b) return ENOMEM;
129 b->budget = *budget_min;
130 b->period = *period_max;
131 b->workload = workload;
132 b->contract_type = contract_type;
134 fres_contract_del_basic(*contract);
135 ret = fres_contract_add_basic(*contract, b);
145 int frsh_contract_get_basic_params
146 (const frsh_contract_t *contract,
147 frsh_rel_time_t *budget_min,
148 frsh_rel_time_t *period_max,
149 frsh_workload_t *workload,
150 frsh_contract_type_t *contract_type)
154 if (!contract || !*contract)
155 return FRSH_ERR_BAD_ARGUMENT;
157 b = fres_contract_get_basic(*contract);
160 *workload = b->workload;
162 *budget_min = b->budget;
164 *period_max = b->period;
166 *contract_type = b->contract_type;
171 int frsh_contract_set_resource_and_label
172 (frsh_contract_t *contract,
173 const frsh_resource_type_t resource_type,
174 const frsh_resource_id_t resource_id,
175 const frsh_contract_label_t contract_label)
177 fres_block_label *label;
178 fres_block_resource *r;
181 if (!contract || !*contract) return FRSH_ERR_BAD_ARGUMENT;
183 r = malloc(sizeof(*r));
184 if (!r) return ENOMEM;
186 r->resource_type = resource_type;
187 r->resource_id = resource_id;
188 fres_contract_del_resource(*contract);
189 ret = fres_contract_add_resource(*contract, r);
197 if (contract_label) {
198 label = malloc(sizeof(*label));
199 if (!label) return ENOMEM;
200 strncpy(label->label, contract_label, sizeof(label->label));
201 label->label[sizeof(label->label)-1] = '\0';
202 fres_contract_del_label(*contract);
203 ret = fres_contract_add_label(*contract, label);
212 int frsh_get_resource_and_label
213 (const frsh_contract_t *contract,
214 frsh_resource_type_t *resource_type,
215 frsh_resource_id_t *resource_id,
216 frsh_contract_label_t contract_label)
218 fres_block_resource *r;
219 fres_block_label *label;
221 if (!contract || !*contract)
222 return FRSH_ERR_BAD_ARGUMENT;
224 if (resource_type || resource_id) {
225 r = fres_contract_get_resource(*contract);
227 *resource_type = r->resource_type;
229 *resource_id = r->resource_id;
232 if (contract_label) {
233 label = fres_contract_get_label(*contract);
234 strncpy(contract_label, label->label, sizeof(label->label));
235 contract_label[sizeof(label->label)-1] = '\0';
241 int frsh_contract_set_timing_reqs
242 (frsh_contract_t *contract,
243 const bool d_equals_t,
244 const frsh_rel_time_t *deadline,
245 const frsh_signal_t budget_overrun_signal,
246 const frsh_signal_info_t budget_overrun_siginfo,
247 const frsh_signal_t deadline_miss_signal,
248 const frsh_signal_info_t deadline_miss_siginfo)
252 fres_block_timing_reqs *t;
254 if (!contract || !*contract)
255 return FRSH_ERR_BAD_ARGUMENT;
257 /* deadline and period must be coherent between each other */
258 b = fres_contract_get_basic(*contract);
260 if ((d_equals_t && deadline != FRSH_NULL_DEADLINE) ||
261 (!d_equals_t && (deadline == FRSH_NULL_DEADLINE)))
262 return FRSH_ERR_BAD_ARGUMENT;
264 /* signal delivery can only be requested for BUONDED workloads */
265 if (b->workload == FRSH_WT_INDETERMINATE &&
266 (deadline_miss_signal != FRSH_NULL_SIGNAL ||
267 budget_overrun_signal != FRSH_NULL_SIGNAL))
268 return FRSH_ERR_BAD_ARGUMENT;
270 t = malloc(sizeof(*t));
271 if (!t) return ENOMEM;
273 t->d_equals_t = d_equals_t;
276 t->deadline = *deadline;
279 return FRSH_ERR_BAD_ARGUMENT;
283 /* Signals are currently ignored by this implementation as
284 * they are better implemented in frsh_thread_bind() */
285 /*t->budget_overrun_signal = budget_overrun_signal;
286 t->budget_overrun_siginfo = budget_overrun_siginfo;
287 t->deadline_miss_signal = deadline_miss_signal;
288 t->deadline_miss_siginfo = deadline_miss_siginfo;*/
289 fres_contract_del_timing_reqs(*contract);
290 ret = fres_contract_add_timing_reqs(*contract, t);
298 int frsh_contract_get_timing_reqs
299 (const frsh_contract_t *contract,
301 frsh_rel_time_t *deadline,
302 frsh_signal_t *budget_overrun_signal,
303 frsh_signal_info_t *budget_overrun_siginfo,
304 frsh_signal_t *deadline_miss_signal,
305 frsh_signal_info_t *deadline_miss_siginfo)
307 fres_block_timing_reqs *t;
309 if (!contract || !*contract)
310 return FRSH_ERR_BAD_ARGUMENT;
312 t = fres_contract_get_timing_reqs(*contract);
315 *d_equals_t = t->d_equals_t;
318 *deadline = t->deadline;
323 int frsh_contract_negotiate
324 (const frsh_contract_t *contract,
325 frsh_vres_id_t *vres)
329 fres_contract_ptr_seq contracts;
330 fres_contract_ptr contracts_buf;
331 fres_contract_id_seq *ids;
332 fres_block_resource *r;
334 if (!contract || !*contract || !vres) {
335 ret = FRSH_ERR_BAD_ARGUMENT;
339 /* Activate allocator */
340 r = fres_contract_get_resource(*contract);
342 fra_activate(r->resource_type,
346 /* Negotiate contract */
347 contracts_buf = *contract;
348 contracts._buffer = &contracts_buf;
349 contracts._length = contracts._maximum = 1;
350 ret = fres_contract_broker_negotiate_contracts(frsh_forb_global.fcb,
353 if (forb_exception_occurred(&env)) {
354 ret = FRES_ERR_FORB_EXCEPTION;
359 assert(ids->_length == 1);
360 *vres = fra_get_vres(&ids->_buffer[0]);
362 if (CORBA_sequence_get_release(ids))
363 CORBA_free(ids->_buffer);
370 int frsh_contract_cancel (const frsh_vres_id_t vres)
374 struct fres_contract *empty_contract;
375 fres_contract_ptr_seq contracts;
376 fres_contract_id_seq *ids;
379 ret = FRSH_ERR_BAD_ARGUMENT;
383 empty_contract = fres_contract_new();
384 empty_contract->id = vres->id;
386 contracts._buffer = &empty_contract;
387 contracts._length = contracts._maximum = 1;
388 ret = fres_contract_broker_negotiate_contracts(frsh_forb_global.fcb,
391 if (forb_exception_occurred(&env)) {
392 ret = FRES_ERR_FORB_EXCEPTION;
396 /* The returned ID is the same as of vres */
397 if (CORBA_sequence_get_release(ids))
398 CORBA_free(ids->_buffer);
404 int frsh_contract_renegotiate_sync
405 (const frsh_contract_t *new_contract,
406 frsh_vres_id_t vres_id)
408 return FRSH_ERR_NOT_IMPLEMENTED;
411 int frsh_contract_renegotiate_async
412 (const frsh_contract_t *new_contract,
414 frsh_signal_t signal_to_notify,
415 frsh_signal_info_t signal_info)
417 return FRSH_ERR_NOT_IMPLEMENTED;
420 int frsh_group_change_mode_sync
421 (const frsh_contracts_group_t *contracts_to_neg,
422 const frsh_contracts_group_t *contracts_to_reneg,
423 const frsh_vres_group_t *vres_to_reneg,
424 const frsh_vres_group_t *vres_to_cancel,
425 frsh_vres_group_t *new_vres)
427 return FRSH_ERR_NOT_IMPLEMENTED;
430 int frsh_group_change_mode_async
431 (const frsh_contracts_group_t *contracts_to_neg,
432 const frsh_contracts_group_t *contracts_to_reneg,
433 const frsh_vres_group_t *vres_to_reneg,
434 const frsh_vres_group_t *vres_to_cancel,
435 const frsh_signal_t signal,
436 const frsh_signal_info_t signal_info,
437 frsh_group_id_t *group)
439 return FRSH_ERR_NOT_IMPLEMENTED;