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;
80 * Registered resource manager
84 struct res_key resource;
85 fres_resource_manager rm; /**< 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 gavl_cust_root_field_t resources;
102 static inline int res_key_cmp(struct res_key *a, struct res_key *b)
104 if (a->type < b->type) {
106 } else if (a->type > b->type) {
108 } else if (a->id < b->id) {
110 } else if (a->id > b->id) {
117 GAVL_CUST_NODE_INT_DEC(fcb_resource /* cust_prefix */, \
118 struct fcb /* cust_root_t */, \
119 struct res_mng /* cust_item_t */, \
120 struct res_key /* cust_key_t */, \
121 resources /* cust_root_node */, \
122 node /* cust_item_node */, \
123 resource /* cust_item_key */, \
124 res_key_cmp /* cust_cmp_fnc */);
126 GAVL_CUST_NODE_INT_IMP(fcb_resource /* cust_prefix */, \
127 struct fcb /* cust_root_t */, \
128 struct res_mng /* cust_item_t */, \
129 struct res_key /* cust_key_t */, \
130 resources /* cust_root_node */, \
131 node /* cust_item_node */, \
132 resource /* cust_item_key */, \
133 res_key_cmp /* cust_cmp_fnc */);
135 GAVL_CUST_NODE_INT_DEC(fcb_alloc /* cust_prefix */, \
136 struct res_mng /* cust_root_t */, \
137 struct res_alloc /* cust_item_t */, \
138 forb_server_id /* cust_key_t */, \
139 allocators /* cust_root_node */, \
140 node /* cust_item_node */, \
141 app /* cust_item_key */, \
142 fres_contract_id_cmp /* cust_cmp_fnc */);
144 GAVL_CUST_NODE_INT_IMP(fcb_alloc /* cust_prefix */, \
145 struct res_mng /* cust_root_t */, \
146 struct res_alloc /* cust_item_t */, \
147 forb_server_id /* cust_key_t */, \
148 allocators /* cust_root_node */, \
149 node /* cust_item_node */, \
150 app /* cust_item_key */, \
151 forb_server_id_cmp /* cust_cmp_fnc */);
154 #define o2fcb(o) (struct fcb*)forb_instance_data(o)
157 negotiate_contract(fres_contract_broker obj,
158 const fres_contract_ptr contract,
159 fres_contract_id_t* id,
160 CORBA_Environment *ev)
162 struct fcb *fcb = o2fcb(obj);
163 fres_block_resource *res;
164 struct res_key res_key;
166 struct res_alloc *ra;
169 fres_contract_ptr contract_seq_buf;
170 fres_contract_ptr_seq contracts;
171 fres_contract_ptr_seq *schedulable_contracts;
172 fres_contract_id_seq ids;
175 res = fres_contract_get_resource(contract);
177 ul_logerr("No resource specified\n");
178 ret = FRSH_ERR_RESOURCE_ID_INVALID;
181 res_key.type = res->resource_type;
182 res_key.id = res->resource_id;
184 rm = fcb_resource_find(fcb, &res_key);
186 ul_logerr("No resource manager for %d.%d registered\n",
187 res_key.type, res_key.id);
192 forb_uuid_generate((forb_uuid_t *)id);
195 forb_get_req_source(obj, &app);
196 ra = fcb_alloc_find(rm, &app);
199 forb_server_id_to_string(str, &app, sizeof(str));
200 ul_logerr("No resource allocator found for %d.%d and %s\n",
201 res_key.type, res_key.id, str);
207 /* Reserve contract */
208 contracts._length = 1;
209 contract_seq_buf = contract;
210 contracts._buffer = &contract_seq_buf;
211 ret = fres_resource_manager_reserve_contracts(rm->rm, &contracts, ev);
212 if (forb_exception_occurred(ev) || ret < 0) {
216 ul_logmsg("Contract was not accepted\n");
220 /* Commit contract */
221 ids._length = ids._maximum = 1;
223 fres_resource_manager_commit_contracts(rm->rm, &ids, &schedulable_contracts, ev);
224 if (forb_exception_occurred(ev)) {
225 ret = FRES_ERR_FORB_EXCEPTION;
230 ret = fres_resource_allocator_change_vreses(ra->ra, schedulable_contracts, ev);
231 if (CORBA_sequence_get_release(schedulable_contracts)) {
233 for (i=0; i<schedulable_contracts->_length; i++) {
234 fres_contract_destroy(schedulable_contracts->_buffer[i]);
236 forb_free(schedulable_contracts->_buffer);
238 forb_free(schedulable_contracts);
239 if (forb_exception_occurred(ev)) {
240 ret = FRES_ERR_FORB_EXCEPTION;
244 ul_logmsg("VRes was not created\n");
253 CORBA_long register_resource(fres_contract_broker obj,
254 const frsh_resource_type_t restype,
255 const frsh_resource_id_t resid,
256 const fres_resource_desc *desc,
257 CORBA_Environment *ev)
259 struct fcb *fcb = o2fcb(obj);
260 struct res_mng *rm, *rm2;
262 rm = malloc(sizeof(*rm));
264 memset(rm, 0, sizeof(*rm));
265 rm->resource.type = restype;
266 rm->resource.id = resid;
267 rm2 = fcb_resource_find(fcb, &rm->resource);
269 if (forb_object_is_stale(rm2->rm)) {
270 ul_logmsg("Removing stale manager for resource %d.%d\n",
272 forb_object_release(rm2->rm);
273 fcb_resource_delete(fcb, rm2);
274 /* TODO: Delete also all allocators associated
275 * with this stale resource manager. */
279 ul_logerr("Resource manager %d.%d already registered\n",
284 rm->rm = forb_object_duplicate(desc->manager);
286 fcb_alloc_init_root_field(rm);
287 ul_logmsg("Registering manager for resource %d.%d\n",
289 fcb_resource_insert(fcb, rm);
298 CORBA_long register_allocator(fres_contract_broker obj,
299 const frsh_resource_type_t restype,
300 const frsh_resource_id_t resid,
301 const fres_resource_allocator ra_obj,
302 CORBA_Environment *ev)
304 struct fcb *fcb = o2fcb(obj);
306 struct res_alloc *ra;
307 struct res_key resource;
308 forb_server_id server_id;
309 char server_id_str[40];
311 forb_get_server_id(ra_obj, &server_id);
312 forb_server_id_to_string(server_id_str, &server_id, sizeof(server_id_str));
313 ul_logmsg("Registering allocator for resource %d.%d in app %s\n",
314 restype, resid, server_id_str);
316 resource.type = restype;
318 rm = fcb_resource_find(fcb, &resource);
320 ul_logerr("No manager found for %d.%d. Unable to register the allocator!\n",
324 ra = fcb_alloc_find(rm, &server_id);
326 char *str = forb_object_to_string(ra_obj);
327 ul_logerr("Allocator from already registered (%s)\n",
332 ra = malloc(sizeof(*ra));
337 ra->ra = forb_object_duplicate(ra_obj);
338 fcb_alloc_insert(rm, ra);
344 struct forb_fres_contract_broker_impl impl = {
345 .negotiate_contract = negotiate_contract,
346 .register_resource = register_resource,
347 .register_allocator = register_allocator,
350 int main(int argc, char *argv[])
354 fres_contract_broker fcb;
355 forb_executor_t executor;
358 orb = forb_init(&argc, &argv, "fcb");
359 if (!orb) error(1, errno, "FORB initialization failed");
361 fcb_resource_init_root_field(&fcb_data);
363 fcb = forb_fres_contract_broker_new(orb, &impl, &fcb_data);
364 if (!fcb) error(1, errno, "forb_fres_contract_broker_new failed");
366 /* Prepare executor before we register the fcb reference,
367 * so that no reuqests are lost */
368 ret = forb_executor_init(&executor);
369 if (ret) error(1, errno, "forb_executor_init failed");
371 ret = forb_executor_register_object(&executor, fcb);
372 if (ret) error(1, errno, "forb_executor_register_object failed");
374 ret = forb_register_reference(fcb, fres_contract_broker_reg_name);
375 if (ret) error(1, errno, "forb_register_reference() failed");
377 ul_logmsg("Waiting for requests\n");
378 ret = forb_executor_run(&executor);
379 if (ret) error(1, errno, "forb_executor_run failed");