]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/thread
530b04539b4a678115760f16bf2211025d183f63
[l4.git] / l4 / pkg / l4sys / include / thread
1 // vi:ft=cpp
2 /**
3  * \file
4  * \brief Common thread related definitions.
5  */
6 /*
7  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8  *               Alexander Warg <warg@os.inf.tu-dresden.de>
9  *     economic rights: Technische Universität Dresden (Germany)
10  *
11  * This file is part of TUD:OS and distributed under the terms of the
12  * GNU General Public License 2.
13  * Please see the COPYING-GPL-2 file for details.
14  *
15  * As a special exception, you may use this file as part of a free software
16  * library without restriction.  Specifically, if other files instantiate
17  * templates or use macros or inline functions from this file, or you compile
18  * this file and link it with other files to produce an executable, this
19  * file does not by itself cause the resulting executable to be covered by
20  * the GNU General Public License.  This exception does not however
21  * invalidate any other reasons why the executable file might be covered by
22  * the GNU General Public License.
23  */
24
25 #pragma once
26
27 #include <l4/sys/capability>
28 #include <l4/sys/thread.h>
29
30 namespace L4 {
31
32 /**
33  * \ingroup l4_thread_api
34  * \brief L4 kernel thread.
35  *
36  * <c>\#include <l4/sys/thread></c>
37  */
38 class Thread : public Kobject_t<Thread, Kobject, L4_PROTO_THREAD>
39 {
40   L4_KOBJECT(Thread)
41
42 public:
43   /**
44    * \copydoc l4_thread_ex_regs()
45    * \note the \a thread argument is the implicit \a this pointer.
46    */
47   l4_msgtag_t ex_regs(l4_addr_t ip, l4_addr_t sp,
48                       l4_umword_t flags,
49                       l4_utcb_t *utcb = l4_utcb()) throw()
50   { return l4_thread_ex_regs_u(cap(), ip, sp, flags, utcb); }
51
52   /**
53    * \copydoc l4_thread_ex_regs_ret()
54    * \note the \a thread argument is the implicit \a this pointer.
55    */
56   l4_msgtag_t ex_regs(l4_addr_t *ip, l4_addr_t *sp,
57                       l4_umword_t *flags,
58                       l4_utcb_t *utcb = l4_utcb()) throw()
59   { return l4_thread_ex_regs_ret_u(cap(), ip, sp, flags, utcb); }
60
61
62   /**
63    * \brief Thread attributes used for control_commit().
64    *
65    * This class is responsible for initalizing various attributes of a
66    * thread in a UTCB for the control_commit() method.
67    *
68    * \see \ref l4_thread_control_api for some more details.
69    */
70   class Attr
71   {
72   private:
73      friend class L4::Thread;
74      l4_utcb_t *_u;
75
76    public:
77      /**
78       * \brief Create a thread-attribute object with the given UTCB.
79       * \param utcb the UTCB to use for the later L4::Thread::control_commit()
80       *             function. Usually this is the UTCB of the calling thread.
81       */
82      explicit Attr(l4_utcb_t *utcb = l4_utcb()) throw() : _u(utcb)
83      { l4_thread_control_start_u(utcb); }
84
85      /**
86       * \brief Set the pager capability selector.
87       * \param pager the capability selector that shall be used for page-fault
88       *              messages. This capability selector must be valid within
89       *              the task the thread is bound to.
90       */
91      void pager(Cap<void> const &pager) throw()
92      { l4_thread_control_pager_u(pager.cap(), _u); }
93
94      /**
95       * \brief Get the capability selector used for page-fault messages.
96       * \return the capability selector used to send page-fault messages. The
97       *         selector is valid in the task the thread is bound to.
98       */
99      Cap<void> pager() throw()
100      { return Cap<void>(l4_utcb_mr_u(_u)->mr[1]); }
101
102      /**
103       * \brief Set the exception-handler capability selector.
104       * \param pager the capability selector that shall be used for exception
105       *              messages. This capability selector must be
106       *              valid within the task the thread is bound to.
107       */
108      void exc_handler(Cap<void> const &exc_handler) throw()
109      { l4_thread_control_exc_handler_u(exc_handler.cap(), _u); }
110
111      /**
112       * \brief Get the capability selector used for exception messages.
113       * \return the capability selector used to send exception messages. The
114       *         selector is valid in the task the thread is bound to.
115       */
116      Cap<void> exc_handler() throw()
117      { return Cap<void>(l4_utcb_mr_u(_u)->mr[2]); }
118
119      /**
120       * \brief Set the scheduler capability selector.
121       * \param pager the capability selector that shall be used for scheduling
122       *              messages. This capability selector must be
123       *              valid within the task the thread is bound to.
124       */
125      void scheduler(Cap<void> const &scheduler) throw()
126      { l4_thread_control_scheduler_u(scheduler.cap(), _u); }
127
128      /**
129       * \brief Get the capability selector used for scheduling messages.
130       * \return the capability selector used to send scheduling messages. The
131       *         selector is valid in the task the thread is bound to.
132       */
133      Cap<void> scheduler() throw()
134      { return Cap<void>(l4_utcb_mr_u(_u)->mr[2]); }
135
136      /**
137       * \brief Bind the thread to a task.
138       * \param thread_utcb the UTCB address of the thread within the task
139       *                    specified by \a task.
140       * \param task        the capability selector for the task the thread
141       *                    shall be bound to.
142       *
143       * Binding a thread to a task means that the thread shall afterwards
144       * execute in the given task. To actually start execution you need
145       * to use L4::Thread::ex_regs().
146       */
147      void bind(l4_utcb_t *thread_utcb, Cap<Task> const &task) throw()
148      { l4_thread_control_bind_u(thread_utcb, task.cap(), _u); }
149
150      /**
151       * \brief Set the thread to alien mode.
152       */
153      void alien(int on) throw()
154      { l4_thread_control_alien_u(_u, on); }
155
156      /**
157       * \brief Allow host system calls on Fiasco-UX.
158       * \pre Running on Fiasco-UX.
159       */
160      void ux_host_syscall(int on) throw()
161      { l4_thread_control_ux_host_syscall_u(_u, on); }
162
163    };
164
165   /**
166    * \brief Commit the given thread-attributes object.
167    * \param attr the attribute object to commit to the thread.
168    */
169   l4_msgtag_t control(Attr const &attr) throw()
170   { return l4_thread_control_commit_u(cap(), attr._u); }
171
172   /**
173    * \brief Switch execution to this thread.
174    * \param utcb the UTCB of the current thread.
175    *
176    * \note The current time slice is inherited to this thread.
177    */
178   l4_msgtag_t switch_to(l4_utcb_t *utcb = l4_utcb()) throw()
179   { return l4_thread_switch_u(cap(), utcb); }
180
181   /**
182    * \brief Get consumed timed of thread in ns.
183    * \param utcb the UTCB of the current thread.
184    *
185    * The consumed time is return as l4_kernel_clock_t at UTCB message
186    * register 0.
187    */
188   l4_msgtag_t stats_time(l4_utcb_t *utcb = l4_utcb()) throw()
189   { return l4_thread_stats_time_u(cap(), utcb); }
190
191   /**
192    * \brief vCPU resume, start.
193    *
194    * \see l4_thread_vcpu_resume_start
195    */
196   l4_msgtag_t vcpu_resume_start(l4_utcb_t *utcb = l4_utcb()) throw()
197   { return l4_thread_vcpu_resume_start_u(utcb); }
198
199   /**
200    * \brief vCPU resume, commit.
201    *
202    * \see l4_thread_vcpu_resume_commit
203    */
204   l4_msgtag_t vcpu_resume_commit(l4_msgtag_t tag,
205                                  l4_utcb_t *utcb = l4_utcb()) throw()
206   { return l4_thread_vcpu_resume_commit_u(cap(), tag, utcb); }
207
208    /**
209     * \copydoc l4_thread_vcpu_control()
210     */
211    l4_msgtag_t vcpu_control(l4_addr_t vcpu_state, l4_utcb_t *utcb = l4_utcb())
212      throw()
213    { return l4_thread_vcpu_control_u(cap(), vcpu_state, utcb); }
214
215    /**
216     * \copydoc l4_thread_vcpu_control_exit()
217     */
218    l4_msgtag_t vcpu_control_ext(l4_addr_t ext_vcpu_state,
219                                 l4_utcb_t *utcb = l4_utcb()) throw()
220    { return l4_thread_vcpu_control_ext_u(cap(), ext_vcpu_state, utcb); }
221
222   /**
223    * \brief Register an IRQ that will trigger upon deletion events.
224    *
225    * \see l4_thread_register_del_irq
226    */
227   l4_msgtag_t register_del_irq(Cap<Irq> irq, l4_utcb_t *u = l4_utcb()) throw()
228   { return l4_thread_register_del_irq_u(cap(), irq.cap(), u); }
229
230   /**
231    * \brief Wrapper class for modifying senders.
232    *
233    * Use the add() function to add modification rules, and use
234    * modify_senders() to commit. Do not use the UTCB inbetween as it is
235    * used by add() and modify_senders().
236    */
237   class Modify_senders
238   {
239   private:
240     friend class Thread;
241     l4_utcb_t *utcb;
242     unsigned cnt;
243
244   public:
245     explicit Modify_senders(l4_utcb_t *u = l4_utcb()) throw()
246     : utcb(u), cnt(1)
247     {
248       l4_utcb_mr_u(utcb)->mr[0] = L4_THREAD_MODIFY_SENDER;
249     }
250
251     /**
252      * \brief Add a rule.
253      *
254      * \param match_mask Bitmask of bits to match the label.
255      * \param match      Bitmask that must be equal to the label after applying
256      *                   match_mask.
257      * \param del_bits   Bits to be deleted from the label.
258      * \param add_bits   Bits to be added to the label.
259      *
260      * \return 0 on sucess, <0 on error
261      *
262      * Only the first match is applied.
263      *
264      * \see l4_thread_modify_sender_add()
265      */
266     int add(l4_umword_t match_mask, l4_umword_t match,
267             l4_umword_t del_bits, l4_umword_t add_bits) throw()
268     {
269       l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
270       if (cnt >= L4_UTCB_GENERIC_DATA_SIZE - 4)
271         return -L4_ENOMEM;
272       m->mr[cnt++] = match_mask;
273       m->mr[cnt++] = match;
274       m->mr[cnt++] = del_bits;
275       m->mr[cnt++] = add_bits;
276       return 0;
277     }
278   };
279
280   /**
281    * \brief Apply sender modifiction rules.
282    *
283    * \param todo   Prepared sender modification rules.
284    *
285    * \return System call return tag.
286    */
287   l4_msgtag_t modify_senders(Modify_senders const &todo) throw()
288   {
289     return l4_ipc_call(cap(), todo.utcb, l4_msgtag(L4_PROTO_THREAD, todo.cnt, 0, 0), L4_IPC_NEVER);
290   }
291 };
292 }