]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/thread
update
[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 Bind the thread to a task.
121       * \param thread_utcb the UTCB address of the thread within the task
122       *                    specified by \a task.
123       * \param task        the capability selector for the task the thread
124       *                    shall be bound to.
125       *
126       * Binding a thread to a task means that the thread shall afterwards
127       * execute in the given task. To actually start execution you need
128       * to use L4::Thread::ex_regs().
129       */
130      void bind(l4_utcb_t *thread_utcb, Cap<Task> const &task) throw()
131      { l4_thread_control_bind_u(thread_utcb, task.cap(), _u); }
132
133      /**
134       * \brief Set the thread to alien mode.
135       */
136      void alien(int on) throw()
137      { l4_thread_control_alien_u(_u, on); }
138
139      /**
140       * \brief Allow host system calls on Fiasco-UX.
141       * \pre Running on Fiasco-UX.
142       */
143      void ux_host_syscall(int on) throw()
144      { l4_thread_control_ux_host_syscall_u(_u, on); }
145
146    };
147
148   /**
149    * \brief Commit the given thread-attributes object.
150    * \param attr the attribute object to commit to the thread.
151    */
152   l4_msgtag_t control(Attr const &attr) throw()
153   { return l4_thread_control_commit_u(cap(), attr._u); }
154
155   /**
156    * \brief Switch execution to this thread.
157    * \param utcb the UTCB of the current thread.
158    *
159    * \note The current time slice is inherited to this thread.
160    */
161   l4_msgtag_t switch_to(l4_utcb_t *utcb = l4_utcb()) throw()
162   { return l4_thread_switch_u(cap(), utcb); }
163
164   /**
165    * \brief Get consumed timed of thread in ns.
166    * \param utcb the UTCB of the current thread.
167    *
168    * The consumed time is return as l4_kernel_clock_t at UTCB message
169    * register 0.
170    */
171   l4_msgtag_t stats_time(l4_utcb_t *utcb = l4_utcb()) throw()
172   { return l4_thread_stats_time_u(cap(), utcb); }
173
174   /**
175    * \brief vCPU resume, start.
176    *
177    * \see l4_thread_vcpu_resume_start
178    */
179   l4_msgtag_t vcpu_resume_start(l4_utcb_t *utcb = l4_utcb()) throw()
180   { return l4_thread_vcpu_resume_start_u(utcb); }
181
182   /**
183    * \brief vCPU resume, commit.
184    *
185    * \see l4_thread_vcpu_resume_commit
186    */
187   l4_msgtag_t vcpu_resume_commit(l4_msgtag_t tag,
188                                  l4_utcb_t *utcb = l4_utcb()) throw()
189   { return l4_thread_vcpu_resume_commit_u(cap(), tag, utcb); }
190
191    /**
192     * \copydoc l4_thread_vcpu_control()
193     */
194    l4_msgtag_t vcpu_control(l4_addr_t vcpu_state, l4_utcb_t *utcb = l4_utcb())
195      throw()
196    { return l4_thread_vcpu_control_u(cap(), vcpu_state, utcb); }
197
198    /**
199     * \copydoc l4_thread_vcpu_control_exit()
200     */
201    l4_msgtag_t vcpu_control_ext(l4_addr_t ext_vcpu_state,
202                                 l4_utcb_t *utcb = l4_utcb()) throw()
203    { return l4_thread_vcpu_control_ext_u(cap(), ext_vcpu_state, utcb); }
204
205   /**
206    * \brief Register an IRQ that will trigger upon deletion events.
207    *
208    * \see l4_thread_register_del_irq
209    */
210   l4_msgtag_t register_del_irq(Cap<Irq> irq, l4_utcb_t *u = l4_utcb()) throw()
211   { return l4_thread_register_del_irq_u(cap(), irq.cap(), u); }
212
213   /**
214    * \brief Wrapper class for modifying senders.
215    *
216    * Use the add() function to add modification rules, and use
217    * modify_senders() to commit. Do not use the UTCB inbetween as it is
218    * used by add() and modify_senders().
219    */
220   class Modify_senders
221   {
222   private:
223     friend class Thread;
224     l4_utcb_t *utcb;
225     unsigned cnt;
226
227   public:
228     explicit Modify_senders(l4_utcb_t *u = l4_utcb()) throw()
229     : utcb(u), cnt(1)
230     {
231       l4_utcb_mr_u(utcb)->mr[0] = L4_THREAD_MODIFY_SENDER;
232     }
233
234     /**
235      * \brief Add a rule.
236      *
237      * \param match_mask Bitmask of bits to match the label.
238      * \param match      Bitmask that must be equal to the label after applying
239      *                   match_mask.
240      * \param del_bits   Bits to be deleted from the label.
241      * \param add_bits   Bits to be added to the label.
242      *
243      * \return 0 on sucess, <0 on error
244      *
245      * Only the first match is applied.
246      *
247      * \see l4_thread_modify_sender_add()
248      */
249     int add(l4_umword_t match_mask, l4_umword_t match,
250             l4_umword_t del_bits, l4_umword_t add_bits) throw()
251     {
252       l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
253       if (cnt >= L4_UTCB_GENERIC_DATA_SIZE - 4)
254         return -L4_ENOMEM;
255       m->mr[cnt++] = match_mask;
256       m->mr[cnt++] = match;
257       m->mr[cnt++] = del_bits;
258       m->mr[cnt++] = add_bits;
259       return 0;
260     }
261   };
262
263   /**
264    * \brief Apply sender modifiction rules.
265    *
266    * \param todo   Prepared sender modification rules.
267    *
268    * \return System call return tag.
269    */
270   l4_msgtag_t modify_senders(Modify_senders const &todo) throw()
271   {
272     return l4_ipc_call(cap(), todo.utcb, l4_msgtag(L4_PROTO_THREAD, todo.cnt, 0, 0), L4_IPC_NEVER);
273   }
274 };
275 }