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 FRESCOR CPUCG (cpu control group) */
27 /* FWP 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. FWP 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 FWP; 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 AQCPU header files in a file, */
39 /* instantiating FWP generics or templates, or linking other files */
40 /* with FWP 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 Dario Faggiolir <faggioli@gandalf.sssup.it>
58 #include <fra_generic.h>
59 #include "diskbfq_contract.h"
62 UL_LOG_CUST(ulogd_fra_cpucg);
63 //ul_log_domain_t ulogd_fra_cpucg = {UL_LOGL_MSG, "fra_cpucg"};
65 static int diskbfq_initialized = 0; /* initialization flag */
68 * Test whether BFQ disk scheduler modue is initialized
70 static inline int diskbfq_is_initialized()
72 return (diskbfq_initialized == 1);
75 static int diskbfq_create_vres(fres_vres_t *vres, void *priv)
77 fres_block_basic *basic;
78 fres_block_disk_sched *disk_sched;
82 * for disk, reserving the bandwidth does not
85 * All that we must do is prepare the
86 * vres storing the I/O priority the thread that
87 * will be bound to it will acquire.
89 fres_contract_id_to_string(id, &vres->id, sizeof(id));
90 basic = fres_contract_get_basic(vres->new);
91 disk_sched = fres_contract_get_disk_sched(vres->new);
92 if (!(vres->priv = malloc(sizeof(int))))
95 memcpy(vres->priv, &disk_sched->ioprio, sizeof(int));
96 printf("Created BFQ VRES (ioprio=%d budget=%ld ms, period=%ld ms)\n",
98 fosa_rel_time_to_msec(basic->budget),
99 fosa_rel_time_to_msec(basic->period));
104 static int diskbfq_cancel_vres(fres_vres_t *vres, void *priv)
112 * As before, it is not possible to "free" disk
115 * All that we do is free vres memory, the bandwidth
116 * is automatically released when the thread is unbound
117 * from the vres itself.
119 printf("Canceled DISK VRES (ioprio=%d)\n", *((int*)vres->priv));
125 int diskbfq_change_vres(fres_vres_t *vres, void *priv)
127 fres_block_disk_sched *disk_sched;
134 disk_sched = fres_contract_get_disk_sched(vres->new);
135 printf("Changed BFQ VRES from ioprio=%d to ioprio=%d\n",
136 *((int*)vres->priv), (int) disk_sched->ioprio);
137 memcpy(vres->priv, &disk_sched->ioprio, sizeof(int));
142 static struct fres_allocator diskbfq_allocator = {
143 .res_type = FRSH_RT_DISK,
144 .res_id = 0, /* DISK ID 0 */
145 .create_vres = diskbfq_create_vres,
146 .cancel_vres = diskbfq_cancel_vres,
147 .change_vres = diskbfq_change_vres,
154 * initialize FRSH for the calling process
156 * Must be called before starting using the framework.
157 * No FRSH call will be successful if this routine is not invoked
159 * Note that no BACKGROUND is created and negotiated and the caller thread
160 * is bound to no BACKGROUND vres, since no way is provided in order of
161 * specifying the contract label and get back the vres id!
163 * Note also that, since in this implementation the threads/processes with
164 * backgound contracts are left into the default Linux scheduler hands' and
165 * not attached to any AQuoSA server, while we're violating what D-AC2v1
166 * (pag. 14) says, we achieve exactly the same behaviour!!
168 * possible return values:
170 * FRSH_ERR_ALREADY_INITIALIZED
171 * FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
173 int diskbfq_fra_init(void)
175 if (diskbfq_is_initialized()) {
179 fres_block_register_disk_sched();
180 if (fra_register(&diskbfq_allocator)) {
184 diskbfq_initialized = 1;
188 int diskbfq_fra_exit()
193 int fra_DISK_bind_thread
194 (const fres_vres_t *vres,
195 const fosa_thread_id_t thread)
198 int ret, ioprio = *((int*)vres->priv);
199 struct fres_contract *contract = vres->perceived;
201 b = fres_contract_get_basic(contract);
202 if (b->contract_type == FRSH_CT_REGULAR)
203 ioprio = DISKBFQ_IOPRIO_DEFAULT;
204 else if (b->contract_type == FRSH_CT_BACKGROUND)
205 ioprio |= IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT;
209 /* ret = ioprio_set(IOPRIO_WHO_PROCESS, gettid(), ioprio); */
210 ret = syscall(__NR_ioprio_set, IOPRIO_WHO_PROCESS,
211 syscall(__NR_gettid), ioprio);
219 int fra_DISK_unbind_thread(const fosa_thread_id_t thread)
223 /* ret = ioprio_set(IOPRIO_WHO_PROCESS, gettid(), IOPRIO_DEFAULT); */
224 ret = syscall(__NR_ioprio_set, IOPRIO_WHO_PROCESS,
225 syscall(__NR_gettid), IOPRIO_PRIO_DEFAULT);
232 int fra_DISK_get_usage
233 (const fres_vres_t *vres,
234 fosa_rel_time_t *spent)
239 int fra_DISK_get_job_usage
240 (const fres_vres_t *vres,
241 fosa_rel_time_t *spent)
246 int fra_DISK_get_remaining_budget
247 (const fres_vres_t *vres,
248 fosa_rel_time_t *budget)
253 int fra_DISK_get_desired_budget
255 frsh_rel_time_t *p_budget_out)
260 int fra_DISK_set_desired_budget
262 fosa_rel_time_t *p_budget_in)
267 int fra_DISK_get_actual_budget
269 fosa_rel_time_t *budget)