2 * (c) 2009 Alexander Warg <warg@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
9 #include "sched_proxy.h"
15 #include <l4/sys/scheduler>
21 blow_up(l4_sched_cpu_set_t const &src, unsigned char gran)
24 gran &= sizeof(l4_umword_t) * 8 - 1;
25 unsigned char og = src.granularity & (sizeof(l4_umword_t) * 8 - 1);
27 n.offset = src.offset & (~0UL << og);
29 for (unsigned i = 0; i < sizeof(l4_umword_t) * 8; ++i)
30 if (src.map & (1UL << (i >> (og - gran))))
37 l4_sched_cpu_set_t operator & (l4_sched_cpu_set_t const &a, l4_sched_cpu_set_t const &b)
39 l4_sched_cpu_set_t _a, _b;
40 unsigned char const ga = a.granularity & (sizeof(l4_umword_t) * 8 - 1);
41 unsigned char const gb = b.granularity & (sizeof(l4_umword_t) * 8 - 1);
58 long ofs_dif = _a.offset - _b.offset;
59 long unsigned abs_ofs_dif;
61 abs_ofs_dif = -ofs_dif;
63 abs_ofs_dif = ofs_dif;
65 if (abs_ofs_dif >= sizeof(l4_umword_t) * 8)
66 return l4_sched_cpu_set(0,0,0);
70 _b.map &= (_a.map >> abs_ofs_dif);
75 _a.map &= (_b.map >> abs_ofs_dif);
80 Sched_proxy::List Sched_proxy::_list;
82 Sched_proxy::Sched_proxy() :
83 Icu(1, &_scheduler_irq),
84 _real_cpus(l4_sched_cpu_set(0,0,0)), _cpu_mask(_real_cpus),
86 _prio_offset(0), _prio_limit(0)
89 _list.push_front(this);
93 Sched_proxy::rescan_cpus()
101 int e = l4_error(L4Re::Env::env()->scheduler()->info(&max, &c));
106 _max_cpus = std::min<unsigned>(sizeof(l4_umword_t) * 8, max);
109 _cpus = _real_cpus & _cpu_mask;
112 Sched_proxy::~Sched_proxy()
118 Sched_proxy::info(l4_umword_t *cpu_max, l4_sched_cpu_set_t *cpus)
120 *cpu_max = _max_cpus;
121 unsigned char g = cpus->granularity & (sizeof(l4_umword_t) * 8 - 1);
122 l4_umword_t offs = cpus->offset & (~0UL << g);
123 if (offs >= _max_cpus)
128 for (unsigned i = offs; i < _max_cpus && b < sizeof(l4_umword_t) * 8;)
130 if (_cpus.map & (1UL << i))
131 cpus->map |= 1UL << b;
135 if (!(i & ~(~0UL << g)))
144 Sched_proxy::run_thread(L4::Cap<L4::Thread> thread, l4_sched_param_t const &sp)
146 l4_sched_param_t s = sp;
147 s.prio = std::min(sp.prio + _prio_offset, _prio_limit);
148 s.affinity = sp.affinity & _cpus;
150 printf("loader[%p] run_thread: o=%u scheduler affinity = %lx sp.m=%lx sp.o=%u sp.g=%u\n",
151 this, _cpus.offset, _cpus.map, sp.affinity.map, (unsigned)sp.affinity.offset, (unsigned)sp.affinity.granularity);
152 printf("loader[%p] sp.m=%lx sp.o=%u sp.g=%u\n",
153 this, s.affinity.map, (unsigned)s.affinity.offset, (unsigned)s.affinity.granularity);
155 return l4_error(L4Re::Env::env()->scheduler()->run_thread(thread, s));
159 Sched_proxy::idle_time(l4_sched_cpu_set_t const &)
160 { return -L4_ENOSYS; }
164 Sched_proxy::received_thread(L4::Ipc::Snd_fpage const &fp)
166 if (!fp.cap_received())
167 return L4::Cap<L4::Thread>::Invalid;
169 return L4::Cap<L4::Thread>(Rcv_cap << L4_CAP_SHIFT);
173 Sched_proxy::restrict_cpus(l4_umword_t cpus)
175 _cpu_mask = l4_sched_cpu_set(0, 0, cpus);
176 _cpus = _real_cpus & _cpu_mask;
180 class Cpu_hotplug_server : public Moe::Server_object
183 int dispatch(l4_umword_t, L4::Ipc::Iostream &)
185 typedef Sched_proxy::List List;
186 for (List::Const_iterator i = Sched_proxy::_list.begin();
187 i != Sched_proxy::_list.end();
198 L4::Cap<L4::Irq> irq = object_pool.cap_alloc()->alloc<L4::Irq>();
201 Err(Err::Fatal).printf("Could not allocate capability for CPU hotplug\n");
205 if (l4_error(l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq.cap())) < 0)
207 Err(Err::Fatal).printf("Could not allocate IRQ for CPU hotplug\n");
211 if (l4_error(irq->attach( l4_umword_t(this), L4::Cap<L4::Thread>(L4_BASE_THREAD_CAP))) < 0)
213 Err(Err::Fatal).printf("Could not attach to CPU hotplug IRQ\n");
217 if (l4_error(L4Re::Env::env()->scheduler()->bind(0, irq)) < 0)
219 Err(Err::Fatal).printf("Could not bind CPU hotplug IRQ to scheduler\n");
225 static Cpu_hotplug_server _cpu_hotplug_server;