On Thu Aug 21, 2014 at 16:18:46 +0200, Valentin Hauner wrote:
On 08/20/2014 07:53 PM, Björn Döbel wrote:
In the second case (PC == 0) that won't work. This looks like someone already performed a jmp/call to address 0. Here you will have to figure out where things go wrong using printf()s. (Or GDB in the qemu scenario...)
Does that help?
Yes, a bit. I decided to debug it with jdb. I've attached the jdb output as well as the main.c with the source code. It's a very small and simple example. The function 'create_edf_thread' matches largely with the main function of your utcb-ipc example, it just sets a different scheduling parameter (deadline based).
Concerning the thread list output, those with id's 25 and 26 are the ones executing the functions thread1() respectively thread2() in main.c. I'm not sure what the state 'exc_progr' means for them in this context. 1b is #threadipc itself, 1e seems to be the main thread of it (but I'm not sure of that).
Does your trained eye see the cause of this error?
The main issue is that you start 2 threads and then immediately leave the main function, which exits your program and would also destroy all threads. But it does not get so far...
static int create_edf_thread(void *func, unsigned deadline) { thread_stacks[count] = malloc(8 << 10);
l4_msgtag_t tag; l4_cap_idx_t thread_cap = l4re_util_cap_alloc();
if (l4_is_invalid_cap(thread_cap)) return -1;
tag = l4_factory_create_thread(l4re_env()->factory, thread_cap); if (l4_error(tag)) return -1;
l4_thread_control_start(); l4_thread_control_pager(l4re_env()->rm); l4_thread_control_exc_handler(l4re_env()->rm); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP);
Each thread needs to have a unique UTCB. In this example, you could fix it like this: l4re_env()->first_free_utcb = (l4_addr_t)l4re_env()->first_free_utcb + L4_UTCB_OFFSET; Remember that the size of the initial UTCB area is limited, so this only works a few times (allocating more is possible).
As both threads use the same UTCB this could result in the behavior you're seeing.
tag = l4_thread_control_commit(thread_cap); if (l4_error(tag)) return -2;
tag = l4_thread_ex_regs(thread_cap, (l4_umword_t)func, (l4_umword_t)(thread_stacks[count] + sizeof(thread_stacks[count])), 0); if (l4_error(tag)) return -3;
l4_sched_param_t sp = l4_sched_param_by_type(Deadline, deadline, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, thread_cap, &sp); if (l4_error(tag)) return -4;
thread_caps[count] = thread_cap;
return count++; }
int main(void) { create_edf_thread(thread1, 1); create_edf_thread(thread2, 3);
Just calling thread() here should also work.
Adam