1// vi:set ft=cpp: -*- Mode: C++ -*-
2/**
3 * \internal
4 * \file
5 * \brief L4::Scheduler server interface
6 */
7/*
8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9 *               Alexander Warg <warg@os.inf.tu-dresden.de>
10 *     economic rights: Technische Universität Dresden (Germany)
11 *
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
15 *
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction.  Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License.  This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
24 */
25#include <l4/sys/scheduler>
26#include <l4/re/util/icu_svr>
27
28#include <l4/sys/cxx/ipc_legacy>
29
30namespace L4kproxy {
31
32class Scheduler_interface
33{
34public:
35  virtual int info(l4_umword_t *cpu_max, l4_sched_cpu_set_t *cpus) = 0;
36
37  virtual int run_thread(L4::Cap<L4::Thread> thread,
38                         l4_sched_param_t const &sp) = 0;
39
40  virtual int idle_time(l4_sched_cpu_set_t const &cpus,
41                        l4_kernel_clock_t &us) = 0;
42
43  virtual ~Scheduler_interface() {}
44};
45
46
47template< typename SVR >
48class Scheduler_svr_t
49{
50public:
51  void hotplug_event() const
52  { this_svr()->scheduler_irq()->trigger(); }
53
54  long op_info(L4::Scheduler::Rights, l4_umword_t gran_offset,
55               l4_umword_t &map, l4_umword_t &cpu_max)
56  {
57    l4_sched_cpu_set_t cpus;
58    cpus.gran_offset = gran_offset;
59    cpus.map = 0;
60
61    int ret = this_svr()->info(&cpu_max, &cpus);
62    map = cpus.map;
63    return ret;
64  }
65
66  long op_idle_time(L4::Scheduler::Rights, l4_sched_cpu_set_t const &cpus,
67                    l4_kernel_clock_t &us)
68  {
69    return this_svr()->idle_time(cpus, us);
70  }
71
72  long op_run_thread(L4::Scheduler::Rights, L4::Ipc::Snd_fpage thread,
73                     l4_sched_param_t const &sp)
74  {
75    return this_svr()->run_thread(this_svr()->received_thread(thread), sp);
76  }
77
78protected:
79  SVR const *this_svr() const { return static_cast<SVR const *>(this); }
80  SVR *this_svr() { return static_cast<SVR *>(this); }
81
82};
83
84
85class Scheduler_svr :
86  public Scheduler_svr_t<Scheduler_svr>,
87  public L4Re::Util::Icu_cap_array_svr<Scheduler_svr>
88{
89  typedef L4Re::Util::Icu_cap_array_svr<Scheduler_svr> Icu;
90  typedef Scheduler_svr_t<Scheduler_svr> Scheduler;
91
92public:
93  L4_RPC_LEGACY_DISPATCH(L4::Scheduler);
94  template<typename IOS> int scheduler_dispatch(unsigned r, IOS &ios)
95  { return dispatch(r, ios); }
96
97  Scheduler_svr(Scheduler_interface *s) : Icu(1, &_scheduler_irq), _sched(s) {}
98  virtual L4::Cap<L4::Thread> received_thread(L4::Ipc::Snd_fpage const &fp) = 0;
99  virtual L4::Ipc_svr::Server_iface *server_iface() const = 0;
100  virtual ~Scheduler_svr() = 0;
101
102  using Icu_svr::op_info;
103  using Scheduler::op_info;
104
105  int info(l4_umword_t *cpu_max, l4_sched_cpu_set_t *cpus)
106  { return _sched->info(cpu_max, cpus); }
107
108  int run_thread(L4::Cap<L4::Thread> thread, l4_sched_param_t const &sp)
109  { return _sched->run_thread(thread, sp); }
110
111  int idle_time(l4_sched_cpu_set_t const &cpus, l4_kernel_clock_t &us)
112  { return _sched->idle_time(cpus, us); }
113
114  Icu::Irq *scheduler_irq() { return &_scheduler_irq; }
115  Icu::Irq const *scheduler_irq() const { return &_scheduler_irq; }
116
117private:
118  Scheduler_interface *_sched;
119  Icu::Irq _scheduler_irq;
120};
121
122inline Scheduler_svr::~Scheduler_svr() {}
123
124}
125