2 * (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU Lesser General Public License 2.1.
7 * Please see the COPYING-LGPL-2.1 file for details.
10 #include <l4/cxx/thread>
11 #include <l4/cxx/iostream>
12 #include <l4/cxx/l4iostream>
14 #include <l4/sys/thread>
15 #include <l4/sys/factory>
16 #include <l4/sys/ipc.h>
18 #include <l4/util/util.h>
21 #include <l4/cxx/ipc_stream>
27 l4_cap_idx_t _next_cap = 20 << L4_CAP_SHIFT;
28 static inline l4_cap_idx_t alloc_next_cap()
29 { l4_cap_idx_t r = _next_cap; _next_cap += (1UL << L4_CAP_SHIFT); return r; }
30 l4_addr_t _next_free_utcb;
34 L4::Cap<void> Thread::_pager;
35 L4::Cap<void> Thread::_master;
36 L4::Cap<void> Thread::_preempter;
38 Thread::Thread( bool /*initiate*/ )
39 : _cap(L4Re::Env::env()->main_thread()), _state(Running)
41 _next_free_utcb = L4Re::Env::env()->first_free_utcb();
43 L4::Thread::Attr attr;
45 _pager = attr.pager();
46 _preempter = attr.scheduler();
47 _utcb_base = l4_addr_t(l4_utcb());
53 l4_msgtag_t err = L4Re::Env::env()->factory()->create_thread(_cap);
54 if (l4_msgtag_has_error(err) || l4_msgtag_label(err) < 0)
55 return l4_msgtag_label(err);
57 L4::Thread::Attr attr(l4_utcb());
59 attr.scheduler(_preempter);
60 attr.bind((l4_utcb_t*)_next_free_utcb, L4Re::This_task);
61 _next_free_utcb += L4_UTCB_OFFSET;
62 return _cap->control(attr).label();
65 Thread::Thread( void *stack )
66 : _cap(alloc_next_cap()), _state(Dead), _stack(stack)
71 Thread::Thread( void *stack, L4::Cap<L4::Thread> const &cap )
72 : _cap(cap), _state(Dead), _stack(stack)
83 *(--((l4_umword_t*&)_stack)) = (l4_umword_t)this;
84 *(--((l4_umword_t*&)_stack)) = 0;
85 _cap->ex_regs((l4_umword_t)start_cxx_thread,
86 (l4_umword_t)_stack, 0);
88 if (l4_msgtag_has_error(l4_ipc_send(_cap.cap(), l4_utcb(),
91 L4::cerr << "ERROR: (master) error while thread handshake: "
92 << _master << "->" << self() << "\n";
96 void Thread::execute()
99 l4_msgtag_t tag = l4_ipc_wait(l4_utcb(), &src, L4_IPC_NEVER);
101 if (l4_msgtag_has_error(tag))
102 L4::cerr << "ERROR: (slave) error while thread handshake: "
109 void Thread::shutdown()
113 l4_ipc_sleep(L4_IPC_NEVER);
119 L4::cerr << "~Thread[" << self() << "]() called from "
120 << l4_myself() << " @" << L4::hex
121 << __builtin_return_address(0) << "\n";
125 *(((l4_umword_t*&)_stack)--) = (l4_umword_t)this;
126 _cap->ex_regs((l4_umword_t)kill_cxx_thread,
127 (l4_umword_t)_stack, 0);