7 #include <l4/sys/capability>
8 #include <l4/sys/thread>
10 #include <l4/sys/factory>
11 #include <l4/re/util/cap_alloc>
12 #include <l4/sys/kdebug.h>
13 #include <l4/sys/scheduler>
15 #include <pthread-l4.h>
22 l4_cap_idx_t pthread_getl4cap(pthread_t thread_id)
24 __volatile__ pthread_descr self = thread_self();
25 pthread_handle handle = thread_handle(thread_id);
28 __pthread_lock(handle_to_lock(handle), self);
29 if (nonexisting_handle(handle, thread_id)) {
30 __pthread_unlock(handle_to_lock(handle));
31 return L4_INVALID_CAP;
34 th = handle_to_descr(handle);
36 __pthread_unlock(handle_to_lock(handle));
40 static void cb(void *arg, pthread_descr th)
42 void (*fn)(pthread_t) = (void (*)(pthread_t))arg;
47 void pthread_l4_for_each_thread(void (*fn)(pthread_t))
49 struct pthread_request request;
51 request.req_thread = thread_self();
52 request.req_kind = REQ_FOR_EACH_THREAD;
53 request.req_args.for_each.arg = (void *)fn;
54 request.req_args.for_each.fn = cb;
56 __pthread_send_manager_rq(&request, 1);
59 // This is a rather temporary solution, it will go away when UTCBs can be
61 l4_utcb_t *pthread_mgr_l4_reserve_consecutive_utcbs(unsigned num)
63 l4_utcb_t *i = __pthread_first_free_handle;
68 l4_utcb_t *s = (l4_utcb_t*)l4_utcb_tcr_u(i)->user[0];
73 && (unsigned long)i + cnt * L4_UTCB_OFFSET == (unsigned long)s)
75 s = (l4_utcb_t*)l4_utcb_tcr_u(s)->user[0];
82 l4_utcb_tcr_u(s)->user[0] = l4_utcb_tcr_u(s)->user[0];
84 __pthread_first_free_handle = (l4_utcb_t*)l4_utcb_tcr_u(s)->user[0];
96 l4_utcb_t *pthread_l4_reserve_consecutive_utcbs(unsigned num)
98 if (l4_is_invalid_cap(__pthread_manager_request))
99 return pthread_mgr_l4_reserve_consecutive_utcbs(num);
101 struct pthread_request request;
103 request.req_thread = thread_self();
104 request.req_kind = REQ_L4_RESERVE_CONSECUTIVE_UTCBS;
105 request.req_args.l4_reserve_consecutive_utcbs.num = num;
108 request.req_args.l4_reserve_consecutive_utcbs.retutcbp = &u;
110 __pthread_send_manager_rq(&request, 1);
115 int __pthread_l4_initialize_main_thread(pthread_descr th)
117 L4Re::Env *env = const_cast<L4Re::Env*>(L4Re::Env::env());
121 L4::Cap<Th_sem_cap> s(env->first_free_cap() << L4_CAP_SHIFT);
122 if (!s.is_valid() || !s.cap())
125 // needed by __alloc_thread_sem
126 th->p_th_cap = env->main_thread().cap();
128 int err = __alloc_thread_sem(th, s);
132 env->first_free_cap((s.cap() + L4_CAP_OFFSET) >> L4_CAP_SHIFT);
134 th->p_thsem_cap = s.cap();
136 th->p_sched_policy = SCHED_L4;
137 th->p_priority = 0x10;
139 th->p_lock = handle_to_lock(l4_utcb());
140 th->p_tid = l4_utcb();
146 int __attribute__((weak)) __pthread_sched_idle_prio = 0x01;
147 int __attribute__((weak)) __pthread_sched_other_prio = 0x02;
148 int __attribute__((weak)) __pthread_sched_rr_prio_min = 0x40;
149 int __attribute__((weak)) __pthread_sched_rr_prio_max = 0xf0;
152 int __pthread_setschedparam(pthread_t thread, int policy,
153 const struct sched_param *param) throw()
155 pthread_handle handle = thread_handle(thread);
158 __pthread_lock(handle_to_lock(handle), NULL);
159 if (__builtin_expect (invalid_handle(handle, thread), 0)) {
160 __pthread_unlock(handle_to_lock(handle));
163 th = handle_to_descr(handle);
164 int prio = __pthread_l4_getprio(policy, param->sched_priority);
167 __pthread_unlock(handle_to_lock(handle));
171 th->p_sched_policy = policy;
172 th->p_priority = param->sched_priority;
175 L4::Cap<L4::Thread> t(th->p_th_cap);
176 l4_sched_param_t sp = l4_sched_param(prio, 0);
177 L4Re::Env::env()->scheduler()->run_thread(t, sp);
179 __pthread_unlock(handle_to_lock(handle));
181 if (__pthread_manager_request > 0)
182 __pthread_manager_adjust_prio(prio);
186 strong_alias (__pthread_setschedparam, pthread_setschedparam)
188 int __pthread_getschedparam(pthread_t thread, int *policy,
189 struct sched_param *param) throw()
191 pthread_handle handle = thread_handle(thread);
194 __pthread_lock(handle_to_lock(handle), NULL);
195 if (__builtin_expect (invalid_handle(handle, thread), 0)) {
196 __pthread_unlock(handle_to_lock(handle));
200 pol = handle_to_descr(handle)->p_sched_policy;
201 prio = handle_to_descr(handle)->p_priority;
202 __pthread_unlock(handle_to_lock(handle));
205 param->sched_priority = prio;
209 strong_alias (__pthread_getschedparam, pthread_getschedparam)