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 /**************************************************************************/
49 * @author Michal Sojka <sojkam1@fel.cvut.cz>
50 * @date Mon Oct 20 18:00:18 2008
52 * @brief FRESCOR Contract Broker
61 #include <ul_gavlcust.h>
64 #include <forb/server_id.h>
65 #include <fres_contract.h>
67 UL_LOG_CUST(ulogd_fcb);
68 ul_log_domain_t ulogd_fcb = {UL_LOGL_MSG, "fcb"};
72 * Resource identification
75 frsh_resource_type_t type;
76 frsh_resource_id_t id;
85 fres_resource_manager mng; /**< Object reference of the resource manager */
86 gavl_cust_root_field_t allocators; /**< Registered allocators for this resource (from multiple applications/nodes) */
90 * Resource allocator registered in different nodes/applications
95 fres_resource_allocator ra;
99 * Contract broker data
102 gavl_cust_root_field_t resources;
105 static inline int res_key_cmp(struct res_key *a, struct res_key *b)
107 if (a->type < b->type) {
109 } else if (a->type > b->type) {
111 } else if (a->id < b->id) {
113 } else if (a->id > b->id) {
120 GAVL_CUST_NODE_INT_DEC(fcb_resource /* cust_prefix */, \
121 struct fcb /* cust_root_t */, \
122 struct resource/* cust_item_t */, \
123 struct res_key /* cust_key_t */, \
124 resources /* cust_root_node */, \
125 node /* cust_item_node */, \
126 key /* cust_item_key */, \
127 res_key_cmp /* cust_cmp_fnc */);
129 GAVL_CUST_NODE_INT_IMP(fcb_resource /* cust_prefix */, \
130 struct fcb /* cust_root_t */, \
131 struct resource/* cust_item_t */, \
132 struct res_key /* cust_key_t */, \
133 resources /* cust_root_node */, \
134 node /* cust_item_node */, \
135 key /* cust_item_key */, \
136 res_key_cmp /* cust_cmp_fnc */);
138 GAVL_CUST_NODE_INT_DEC(fcb_alloc /* cust_prefix */, \
139 struct resource /* cust_root_t */, \
140 struct res_alloc /* cust_item_t */, \
141 forb_server_id /* cust_key_t */, \
142 allocators /* cust_root_node */, \
143 node /* cust_item_node */, \
144 app /* cust_item_key */, \
145 fres_contract_id_cmp /* cust_cmp_fnc */);
147 GAVL_CUST_NODE_INT_IMP(fcb_alloc /* cust_prefix */, \
148 struct resource /* cust_root_t */, \
149 struct res_alloc /* cust_item_t */, \
150 forb_server_id /* cust_key_t */, \
151 allocators /* cust_root_node */, \
152 node /* cust_item_node */, \
153 app /* cust_item_key */, \
154 forb_server_id_cmp /* cust_cmp_fnc */);
157 #define o2fcb(o) (struct fcb*)forb_instance_data(o)
160 negotiate_contract(fres_contract_broker obj,
161 const fres_contract_ptr contract,
162 fres_contract_id_t* id,
163 CORBA_Environment *ev)
165 struct fcb *fcb = o2fcb(obj);
166 fres_block_resource *block_res;
167 struct res_key res_key;
168 struct resource *resource;
169 struct res_alloc *ra;
172 fres_contract_ptr contract_seq_buf;
173 fres_contract_ptr_seq contracts;
174 fres_contract_ptr_seq *schedulable_contracts;
175 fres_contract_id_seq ids;
178 block_res = fres_contract_get_resource(contract);
180 ul_logerr("No resource specified\n");
181 ret = FRSH_ERR_RESOURCE_ID_INVALID;
184 res_key.type = block_res->resource_type;
185 res_key.id = block_res->resource_id;
187 resource = fcb_resource_find(fcb, &res_key);
189 ul_logerr("No resource manager for %d.%d registered\n",
190 res_key.type, res_key.id);
195 forb_uuid_generate((forb_uuid_t *)id);
198 forb_get_req_source(obj, &app);
199 ra = fcb_alloc_find(resource, &app);
202 forb_server_id_to_string(str, &app, sizeof(str));
203 ul_logerr("No resource allocator found for %d.%d and %s\n",
204 res_key.type, res_key.id, str);
210 /* Reserve contract */
211 contracts._length = 1;
212 contract_seq_buf = contract;
213 contracts._buffer = &contract_seq_buf;
214 ret = fres_resource_manager_reserve_contracts(resource->mng, &contracts, ev);
215 if (forb_exception_occurred(ev) || ret < 0) {
219 ul_logmsg("Contract was not accepted\n");
223 /* Commit contract */
224 ids._length = ids._maximum = 1;
226 fres_resource_manager_commit_contracts(resource->mng, &ids,
227 &schedulable_contracts, ev);
228 if (forb_exception_occurred(ev)) {
229 ret = FRES_ERR_FORB_EXCEPTION;
234 ret = fres_resource_allocator_change_vreses(ra->ra, schedulable_contracts, ev);
235 if (CORBA_sequence_get_release(schedulable_contracts)) {
237 for (i=0; i<schedulable_contracts->_length; i++) {
238 fres_contract_destroy(schedulable_contracts->_buffer[i]);
240 forb_free(schedulable_contracts->_buffer);
242 forb_free(schedulable_contracts);
243 if (forb_exception_occurred(ev)) {
244 ret = FRES_ERR_FORB_EXCEPTION;
248 ul_logmsg("VRes was not created\n");
257 CORBA_long register_resource(fres_contract_broker obj,
258 const frsh_resource_type_t restype,
259 const frsh_resource_id_t resid,
260 const fres_resource_desc *desc,
261 CORBA_Environment *ev)
263 struct fcb *fcb = o2fcb(obj);
264 struct resource *res, *res2;
266 res = malloc(sizeof(*res));
268 memset(res, 0, sizeof(*res));
269 res->key.type = restype;
271 res2 = fcb_resource_find(fcb, &res->key);
273 if (forb_object_is_stale(res2->mng)) {
274 ul_logmsg("Removing stale manager for resource %d.%d\n",
276 forb_object_release(res2->mng);
277 fcb_resource_delete(fcb, res2);
278 /* TODO: Delete also all allocators associated
279 * with this stale resource manager. */
283 ul_logerr("Resource manager %d.%d already registered\n",
288 res->mng = forb_object_duplicate(desc->manager);
290 fcb_alloc_init_root_field(res);
291 ul_logmsg("Registering manager for resource %d.%d\n",
293 fcb_resource_insert(fcb, res);
302 CORBA_long register_allocator(fres_contract_broker obj,
303 const frsh_resource_type_t restype,
304 const frsh_resource_id_t resid,
305 const fres_resource_allocator ra_obj,
306 CORBA_Environment *ev)
308 struct fcb *fcb = o2fcb(obj);
309 struct resource *res;
310 struct res_alloc *ra;
311 struct res_key resource;
312 forb_server_id server_id;
313 char server_id_str[40];
315 forb_get_server_id(ra_obj, &server_id);
316 forb_server_id_to_string(server_id_str, &server_id, sizeof(server_id_str));
317 ul_logmsg("Registering allocator for resource %d.%d in app %s\n",
318 restype, resid, server_id_str);
320 resource.type = restype;
322 res = fcb_resource_find(fcb, &resource);
324 ul_logerr("No manager found for %d.%d. Unable to register the allocator!\n",
328 ra = fcb_alloc_find(res, &server_id);
330 char *str = forb_object_to_string(ra_obj);
331 ul_logerr("Allocator from already registered (%s)\n",
336 ra = malloc(sizeof(*ra));
341 ra->ra = forb_object_duplicate(ra_obj);
342 fcb_alloc_insert(res, ra);
348 struct forb_fres_contract_broker_impl impl = {
349 .negotiate_contract = negotiate_contract,
350 .register_resource = register_resource,
351 .register_allocator = register_allocator,
354 int main(int argc, char *argv[])
358 fres_contract_broker fcb;
359 forb_executor_t executor;
362 orb = forb_init(&argc, &argv, "fcb");
363 if (!orb) error(1, errno, "FORB initialization failed");
365 fcb_resource_init_root_field(&fcb_data);
367 fcb = forb_fres_contract_broker_new(orb, &impl, &fcb_data);
368 if (!fcb) error(1, errno, "forb_fres_contract_broker_new failed");
370 /* Prepare executor before we register the fcb reference,
371 * so that no reuqests are lost */
372 ret = forb_executor_init(&executor);
373 if (ret) error(1, errno, "forb_executor_init failed");
375 ret = forb_executor_register_object(&executor, fcb);
376 if (ret) error(1, errno, "forb_executor_register_object failed");
378 ret = forb_register_reference(fcb, fres_contract_broker_reg_name);
379 if (ret) error(1, errno, "forb_register_reference() failed");
381 ul_logmsg("Waiting for requests\n");
382 ret = forb_executor_run(&executor);
383 if (ret) error(1, errno, "forb_executor_run failed");