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;
struct fres_contract *schedulable_contract;
};
+struct fcb_transaction {
+ char *name;
+ gavl_node_t node;
+ gsa_array_field_t contracts;
+};
+
/**
* Contract broker data
*/
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)
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)
{
#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;
};
}
vreses._buffer[vreses._length] = sc;
vreses._length++;
- fres_contract_destroy(fc->schedulable_contract);
- fc->schedulable_contract = fres_contract_duplicate(sc);
last_ra = fc->ra;
}
* 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;
/* See the note above. */
}
}
+ for (i=0; i<schedulable_contracts->_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;
}
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)
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)) {
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;
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");