]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - fres/resmng/frm_generic.c
Generic part of resource manager was moved libfrm
[frescor/frsh.git] / fres / resmng / frm_generic.c
1 #include <frm_generic.h>
2 #include <forb.h>
3 #include <ul_log.h>
4 #include <fres_sa_scenario.h>
5 #include <fcb.h>
6
7 UL_LOG_CUST(ulogd_frm);
8 ul_log_domain_t ulogd_frm = {UL_LOGL_MSG, "frm"};
9
10 struct frm_data {
11         struct fres_sa_scenario *running;
12         frm_adm_test_fnc_t admission_test;
13         void *priv;
14 };
15
16 #define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
17 #define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
18
19 static CORBA_long reserve_contracts(fres_resource_manager obj,
20                              const fres_contract_ptr_seq* contracts,
21                              CORBA_Environment *ev)
22 {
23         struct frm_data *frm = object_to_frm(obj);
24         struct fres_sa_scenario *prospective;
25         struct fres_contract *c;
26         bool schedulable;
27         int i;
28
29         ul_logdeb("reserve_contracts\n");
30         
31         prospective = fres_sa_scenario_duplicate(frm->running);
32         for (i=0; i<contracts->_length; i++) {
33                 c = fres_contract_duplicate(contracts->_buffer[i]);
34                 fres_sa_scenario_add_contract(prospective, c);
35         }
36
37         schedulable = frm->admission_test(prospective, frm->priv);
38
39         if (schedulable) {
40                 fres_sa_scenario_destroy(frm->running);
41                 frm->running = prospective;
42         } else {
43                 fres_sa_scenario_destroy(prospective);
44         }
45         return schedulable ? 0 : 1;
46 }
47
48 static void commit_contracts(fres_resource_manager obj,
49                       const fres_contract_id_seq* ids,
50                       fres_contract_ptr_seq** contract_with_scheduler_data,
51                       CORBA_Environment *ev)
52 {
53         struct frm_data *frm = object_to_frm(obj);
54         int i, num;
55         struct fres_sa_contract *c;
56         fres_contract_ptr_seq *contracts;
57
58         ul_logdeb("commit_contracts\n");
59
60         contracts = forb_malloc(sizeof(*contracts));
61         if (!contracts) {
62                 ev->major = FORB_EX_NO_MEMORY;
63                 goto err;
64         }
65         num = ids->_length;
66         contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
67         contracts->_maximum = contracts->_length = num;
68         
69         for (i=0; i < num; i++) {
70                 c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
71         }
72         
73         *contract_with_scheduler_data = contracts;
74 err:;
75 }
76
77 static void cancel_contracts(fres_resource_manager obj,
78                       const fres_contract_id_seq* ids,
79                       CORBA_Environment *ev)
80 {
81         int i;
82         struct frm_data *frm = object_to_frm(obj);
83
84         ul_logdeb("cancel_contracts\n");
85
86         for (i=0; i<ids->_length; i++) {
87                 struct fres_sa_contract *c;
88                 c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
89
90                 if (c) {
91                         fres_sa_scenario_del_contract(frm->running, c);
92                 }
93         }
94 }
95
96
97 static const struct forb_fres_resource_manager_impl frm_impl = {
98         .reserve_contracts = reserve_contracts,
99         .commit_contracts  = commit_contracts,
100         .cancel_contracts  = cancel_contracts,
101 };
102
103 /** 
104  * Initializes and runs a generic resource manager. The only thing a
105  * caller has to supply is admission test function, which is passed in
106  * @a frm_data->admission_test.
107  * 
108  * @param orb FORB object used to communicate with other components.
109  * @param admission_test Admission test function.
110  * @param priv Pointer to passed as priv parameter to frm_adm_test_fnc_t.
111  * 
112  * @return 
113  */
114 int frm_generic_run(forb_orb orb, frm_adm_test_fnc_t admission_test, void *priv)
115 {
116         fres_contract_broker fcb;
117         fres_resource_manager frm;
118         struct forb_env env;
119         struct frm_data frm_data;
120
121         memset(&frm_data, 0, sizeof(frm_data));
122         frm_data.admission_test = admission_test;
123         frm_data.priv = priv;
124
125         fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
126         if (!fcb) {
127                 save_errno(ul_logerr("Could not find contract broker"));
128                 goto err;
129         }
130
131         frm = forb_fres_resource_manager_new(orb, &frm_impl, &frm_data);
132         if (!frm) {
133                 save_errno(ul_logerr("forb_fres_resource_manager_new error"));
134                 goto err_release_fcb;
135         }
136
137         fres_contract_broker_register_manager(fcb, FRSH_RT_PROCESSOR, 0,
138                                               frm, &env);
139         if (forb_exception_occured(&env)) {
140                 goto err_release_frm;
141         }
142
143         forb_execute_object(frm);
144         return 0;
145
146 err_release_frm:        
147         forb_object_release(frm);
148 err_release_fcb:        
149         forb_object_release(fcb);
150 err:
151         return -1;
152 }