From: Michal Sojka Date: Fri, 25 Jun 2010 12:38:08 +0000 (+0200) Subject: negotiate_transaction() hopefully completed X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/frsh.git/commitdiff_plain/6af520702e1d3f606bfc3994470310ef5976fa19 negotiate_transaction() hopefully completed --- diff --git a/fres/cbroker/fcb.c b/fres/cbroker/fcb.c index 26aea51..5d7018d 100644 --- a/fres/cbroker/fcb.c +++ b/fres/cbroker/fcb.c @@ -125,12 +125,15 @@ struct res_alloc { fres_resource_allocator ra; }; +struct fcb_transaction; + struct fcb_contract { fres_contract_id_t id; struct res_alloc *ra; /**< Allocator for this contract TODO: Remove contract if allocator is destroyed */ gavl_node_t node_fcb; ul_list_node_t node_sc; ul_list_node_t node_reservation; + struct fcb_transaction *transaction; struct { int initial; int try; @@ -142,6 +145,12 @@ struct fcb_contract { struct fres_contract *schedulable_contract; }; +struct fcb_transaction { + char *name; + gavl_node_t node; + gsa_array_field_t contracts; +}; + /** * Contract broker data */ @@ -149,6 +158,7 @@ struct fcb { fres_contract_id_t contract_counter; gavl_cust_root_field_t resources; /**< Registered resources */ gavl_cust_root_field_t contracts; /**< Contracts negotiated by this FCB */ + gavl_cust_root_field_t transactions; /**< Transactions negotiated by this FCB */ }; struct fcb_contract *fcb_contract_new(fres_contract_id_t *id) @@ -182,6 +192,50 @@ void fcb_contract_destroy(struct fcb_contract *fcb_contract) free(fcb_contract); } +static inline int +unsorted(const void *a, const void *b) +{ abort(); } + +/* Unordered dynamic array of contracts in transaction */ +GSA_CUST_DEC(tran_contract /* cust_prefix */, + struct fcb_transaction /* cust_array_t */, + struct fcb_contract/* cust_item_t */, + fres_contract_id_t /* cust_key_t */, + contracts /* cust_array_field */, + id /* cust_item_key */, + unsorted /* cust_cmp_fnc */); + +GSA_CUST_IMP(tran_contract /* cust_prefix */, + struct fcb_transaction /* cust_array_t */, + struct fcb_contract/* cust_item_t */, + fres_contract_id_t /* cust_key_t */, + contracts /* cust_array_field */, + id /* cust_item_key */, + unsorted /* cust_cmp_fnc */, + true /* cust_ins_fl */); + +struct fcb_transaction *fcb_transaction_new(char *name) +{ + struct fcb_transaction *fcb_transaction; + + fcb_transaction = malloc(sizeof(*fcb_transaction)); + if (!fcb_transaction) { + return NULL; + } + memset(fcb_transaction, 0, sizeof(*fcb_transaction)); + fcb_transaction->name = strdup(name); + + tran_contract_init_array_field(fcb_transaction); + + return fcb_transaction; +} + +void fcb_transaction_destroy(struct fcb_transaction *fcb_transaction) +{ + free(fcb_transaction->name); + free(fcb_transaction); +} + static inline int res_key_cmp(const struct res_key *a, const struct res_key *b) { @@ -272,6 +326,28 @@ GAVL_CUST_NODE_INT_IMP(fcb_contract /* cust_prefix */, \ #include "fcb_contract_gavl.inc" #endif +static inline int +fcb_transaction_cmp(char * const *a, char * const *b) +{ return strcmp(*a, *b); } + +GAVL_CUST_NODE_INT_DEC(fcb_transaction /* cust_prefix */, \ + struct fcb /* cust_root_t */, \ + struct fcb_transaction /* cust_item_t */, \ + char* /* cust_key_t */, \ + transactions /* cust_root_node */, \ + node /* cust_item_node */, \ + name /* cust_item_key */, \ + fcb_transaction_cmp /* cust_cmp_fnc */); + +GAVL_CUST_NODE_INT_IMP(fcb_transaction /* cust_prefix */, \ + struct fcb /* cust_root_t */, \ + struct fcb_transaction /* cust_item_t */, \ + char* /* cust_key_t */, \ + transactions /* cust_root_node */, \ + node /* cust_item_node */, \ + name /* cust_item_key */, \ + fcb_transaction_cmp /* cust_cmp_fnc */); + struct res_array { gsa_array_field_t array; }; @@ -668,8 +744,6 @@ change_vreses(struct fcb *fcb, fres_contract_ptr_seq *schedulable_contracts) } vreses._buffer[vreses._length] = sc; vreses._length++; - fres_contract_destroy(fc->schedulable_contract); - fc->schedulable_contract = fres_contract_duplicate(sc); last_ra = fc->ra; } @@ -772,8 +846,8 @@ err: * reference. Canceled contracts are removed below. */ int fcb_remember_contracts(struct fcb *fcb, - struct fcb_contract **fcb_contracts, - int num) + struct fcb_contract **fcb_contracts, int num, + fres_contract_ptr_seq *schedulable_contracts) { struct fcb_contract *fc; int i; @@ -799,6 +873,14 @@ fcb_remember_contracts(struct fcb *fcb, /* See the note above. */ } } + for (i=0; i_length; i++) { + struct fres_contract *sc = schedulable_contracts->_buffer[i]; + fc = fcb_contract_find(fcb, &sc->id); + assert(fc != NULL); + fres_contract_destroy(fc->schedulable_contract); + fc->schedulable_contract = fres_contract_duplicate(sc); + } + return 0; } @@ -864,7 +946,8 @@ negotiate_contracts(fres_contract_broker obj, if (ret) goto err_cancel_reservation; - fcb_remember_contracts(fcb, fcb_contracts, num); + fcb_remember_contracts(fcb, fcb_contracts, num, + schedulable_contracts); ret = change_vreses(fcb, schedulable_contracts); if (ret) @@ -1113,6 +1196,7 @@ negotiate_transaction(fres_contract_broker _obj, struct res_key key; struct resource *resource; fres_contract_ptr_seq *schedulable_contracts; + struct fcb_transaction *ft; ul_logmsg("Negotiating transaction with %d contracts\n", num); if (transaction_has_spare_capacity(transaction)) { @@ -1161,8 +1245,20 @@ negotiate_transaction(fres_contract_broker _obj, goto err_cancel_reservation; } } - fcb_remember_contracts(fcb, fcb_contracts, num); + fcb_remember_contracts(fcb, fcb_contracts, num, + schedulable_contracts); forb_sequence_free(schedulable_contracts, fres_contract_ptr_destroy); + + ft = fcb_transaction_new(transaction->name); + if (!ft) { + ret = errno; + goto err_cancel_reservation; + } + for (i = 0; i < num; i++) { + tran_contract_insert_at(ft, fcb_contracts[i], i); + fcb_contracts[i]->transaction = ft; + } + fcb_transaction_insert(fcb, ft); res_array_delete_all(&res_array); return 0; @@ -1333,6 +1429,7 @@ int main(int argc, char *argv[]) fcb_resource_init_root_field(&fcb_data); fcb_contract_init_root_field(&fcb_data); + fcb_transaction_init_root_field(&fcb_data); fcb = forb_fres_contract_broker_new(orb, &impl, &fcb_data); if (!fcb) error(1, errno, "forb_fres_contract_broker_new failed");