From b3548feae7b302ed92611b47d250956e8d5765fa Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Thu, 24 Jun 2010 16:56:46 +0200 Subject: [PATCH] fcb: Add reserve_resource helper function TODO: Fix a bug in the implementation - test suite fails! --- fres/cbroker/fcb.c | 186 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 140 insertions(+), 46 deletions(-) diff --git a/fres/cbroker/fcb.c b/fres/cbroker/fcb.c index 2e825bc..83d314d 100644 --- a/fres/cbroker/fcb.c +++ b/fres/cbroker/fcb.c @@ -53,6 +53,7 @@ * * */ +#define WITH_C99 /* For ul_gsa.h iterators */ #include #include #include @@ -63,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -265,6 +267,28 @@ GAVL_CUST_NODE_INT_IMP(fcb_contract /* cust_prefix */, \ #include "fcb_contract_gavl.inc" #endif +struct res_array { + gsa_array_field_t array; +}; + +GSA_CUST_DEC(res_array /* cust_prefix */, + struct res_array /* cust_array_t */, + struct resource /* cust_item_t */, + struct res_key /* cust_key_t */, + array /* cust_array_field */, + key /* cust_item_key */, + res_key_cmp /* cust_cmp_fnc */); + +GSA_CUST_IMP(res_array /* cust_prefix */, + struct res_array /* cust_array_t */, + struct resource /* cust_item_t */, + struct res_key /* cust_key_t */, + array /* cust_array_field */, + key /* cust_item_key */, + res_key_cmp /* cust_cmp_fnc */, + true /* cust_ins_fl */); + + #define o2fcb(o) (struct fcb*)forb_instance_data(o) @@ -439,6 +463,53 @@ prepare_reservation_list(struct resource *resource, } } +static int +reserve_resource(struct resource *resource) +{ + int ret, i; + fres_contract_ptr_seq contracts; + struct fres_contract *c; + struct fcb_contract *fc; + CORBA_Environment ev; + + if (!forb_sequence_alloc_buf(&contracts, resource->rl.length)) { + ret = errno; + goto err; + } + forb_sequence_length(&contracts) = resource->rl.length; + + i=0; + /* Prepare FORB sequence */ + ul_list_for_each(reservation_list, &resource->rl, fc) { + c = NULL; + if (fc->to_be_reserved_contract) + /* Contract without spare capacity */ + c = fc->to_be_reserved_contract; + else if (fc->requested_contract) + c = fc->requested_contract; + assert(c); + forb_sequence_elem(&contracts, i++) = c; + } + + /* Reserve contract */ + ret = fres_resource_manager_reserve_contracts(resource->mng, &contracts, &ev); + if (forb_exception_occurred(&ev)) { + ret = fres_forbex2err(&ev); + ul_logerr("FORB exception when reserving contracts\n"); + goto err_free; + } + if (ret < 0) { + ul_logerr("Contract reservation error %d\n", ret); + ret = FRES_ERR_ADMISSION_TEST; + goto err_free; + } + ret = 0; +err_free: + forb_sequence_free_buf(&contracts, forb_no_destructor); +err: + return ret; +} + /** * * @@ -451,17 +522,10 @@ static int rebalance_spare_capacity_and_reserve(struct resource *resource) { int ret; - unsigned i; struct reservation_list *rl = &resource->rl; struct fcb_contract *fc; fres_block_spare_capacity *s; - fres_contract_ptr_seq contracts; - if (!forb_sequence_alloc_buf(&contracts, rl->length)) { - return errno; - } - contracts._length = rl->length; - i=0; /* Initialize optimization */ ul_list_for_each(reservation_list, rl, fc) { fc->to_be_reserved_contract = @@ -470,9 +534,6 @@ rebalance_spare_capacity_and_reserve(struct resource *resource) NULL; assert(fc->to_be_reserved_contract != NULL); - forb_sequence_elem(&contracts, i) = fc->to_be_reserved_contract; - i++; - s = fres_contract_get_spare_capacity(fc->to_be_reserved_contract); if (s && s->granularity == FRSH_GR_DISCRETE) { fc->sc_variant.initial = s->variants._length - 1; @@ -516,22 +577,12 @@ rebalance_spare_capacity_and_reserve(struct resource *resource) } if (criterion > best_criterion) { - CORBA_Environment ev; - /* Reserve contract */ - ret = fres_resource_manager_reserve_contracts(resource->mng, &contracts, &ev); - if (forb_exception_occurred(&ev)) { - ret = fres_forbex2err(&ev); - ul_logerr("FORB exception when reserving contracts\n"); + ret = reserve_resource(resource); + if (ret) goto err; - } - if (ret < 0) { - ul_logerr("Contract reservation error %d\n", ret); - ret = FRES_ERR_ADMISSION_TEST; - goto err; - } - if (ret == 0) { /* negotiation succeeded */ - best_criterion = criterion; - } + + /* negotiation succeeded */ + best_criterion = criterion; } } while (!all_combinations_tried); @@ -553,7 +604,6 @@ err: fres_contract_destroy(fc->to_be_reserved_contract); fc->to_be_reserved_contract = NULL; } - forb_sequence_free_buf(&contracts, forb_no_destructor); return ret; } @@ -1002,39 +1052,43 @@ transaction_has_spare_capacity(const fres_transaction_t* transaction) static int transaction_get_resources(struct fcb *fcb, struct fcb_contract *fc[], - int num, struct resource **resources[]) + int num, struct res_array *res_array) { - int i, j, r, alloc; - struct resource **res; + int i; struct resource *resource; struct res_key key; + int ret; - alloc = 10; - res = malloc(alloc*sizeof(*res)); - if (!res) - return errno; - res[0] = NULL; - for (r = 0, i = 0; i < num; i++) { + res_array_init_array_field(res_array); + for (i = 0; i < num; i++) { get_fc_res_key(fc[i], &key); resource = fcb_resource_find(fcb, &key); - /* TODO: Check whether to use GSA for resources. */ + ret = res_array_insert(res_array, resource); + if (ret == -1) { + ret = FRSH_ERR_INTERNAL_ERROR; + goto err; + } } - res[r] = NULL; - return 0; + ret = 0; +err: + return ret; } - - CORBA_long negotiate_transaction(fres_contract_broker _obj, const fres_transaction_t* transaction, CORBA_Environment *ev) { struct fcb *fcb = o2fcb(_obj); - struct fcb_contract **fcb_contracts; - const fres_contract_ptr_seq* contracts = &transaction->contracts; - int num = contracts->_length; + struct fcb_contract **fcb_contracts, *fc; + const fres_contract_ptr_seq* user_contracts = &transaction->contracts; + int num = user_contracts->_length; int ret; + struct res_array res_array; + fres_contract_ptr_seq res_contracts; + int i, j; + struct res_key key; + struct resource *resource; if (transaction_has_spare_capacity(transaction)) { ret = FRES_ERR_SPARE_CAPACITY_NOT_SUPPORTED; @@ -1049,13 +1103,53 @@ negotiate_transaction(fres_contract_broker _obj, memset(fcb_contracts, 0, sizeof(*fcb_contracts)*num); ret = prepare_fcb_contracts(fcb, fcb_contracts, - contracts->_buffer, num); + user_contracts->_buffer, num); if (ret) goto err_free_fcb_contracts; - //ret = transaction_get_resources(fcb_contracts, num, &resources); + ret = transaction_get_resources(fcb, fcb_contracts, num, &res_array); + + if (!forb_sequence_alloc_buf(&res_contracts, num)) { + ret = errno; + goto err_free_resources; + } + + gsa_cust_for_each(res_array, &res_array, resource) { + reservation_list_init_head(&resource->rl); + resource->rl.length = 0; + for (i = 0; i < num; i++) { + fc = fcb_contracts[i]; + get_fc_res_key(fc, &key); + if (res_key_cmp(&key, &resource->key) == 0) { + reservation_list_insert(&resource->rl, fc); + resource->rl.length++; + } + } + } +/* gsa_cust_for_each(res_array, &res_array, resource) { */ +/* CORBA_Environment ev; */ +/* /\* Reserve contract *\/ */ +/* reservation_list2s */ +/* ret = fres_resource_manager_reserve_contracts(resource->mng, &res_contracts, &ev); */ +/* if (forb_exception_occurred(&ev)) { */ +/* ret = fres_forbex2err(&ev); */ +/* ul_logerr("FORB exception when reserving contracts\n"); */ +/* goto err_free_res_contracts; */ +/* } */ +/* if (ret < 0) { */ +/* ul_logerr("Contract reservation error %d\n", ret); */ +/* ret = FRES_ERR_ADMISSION_TEST; */ +/* goto err; */ +/* } */ +/* if (ret == 0) { /\* negotiation succeeded *\/ */ +/* } */ +/* } */ - return FRSH_ERR_NOT_IMPLEMENTED; + return 0; +err_free_res_contracts: + forb_sequence_free_buf(&res_contracts, forb_no_destructor); +err_free_resources: + res_array_delete_all(&res_array); err_free_fcb_contracts: free_fcb_contracts(fcb_contracts, num); err: -- 2.39.2