l4/sys/syscalls.h: No such file or directory

Adam Lackorzynski adam at os.inf.tu-dresden.de
Wed Sep 3 00:32:49 CEST 2014


On Tue Sep 02, 2014 at 11:19:35 +0200, Valentin Hauner wrote:
> Hi,
> 
> On 09/02/2014 12:27 AM, Adam Lackorzynski wrote:
> > Most use the C++ interface, so looking for 'create_task' is better.
> > Why not use ned for creating tasks?
> My whole EDF library is written in C now, so switching to C++ or Lua
> makes it very uncomfortable for me.

No problem. There are both C and C++ variants of each function so you
can also look at C++ code to see how things are arranged and use C in
your code.

> On 09/02/2014 12:27 AM, Adam Lackorzynski wrote:
> > Also, the size argument of l4_fpage is the
> > size in log2, so maybe 12 is a good number (the minimum because it's a
> > page).
> Thanks, that part is working now. The new tasks are created properly and
> displayed as 'ready' in the JDB thread list.
> 
> But there's another problem: Using the region mapper of the current task
> does not work for the newly created tasks, of course.
> I've attached a small example that illustrates the problem (task
> creation: lines 19-25, setting pager and exception handler: lines
> 40-48). I've tried to make it as small as possible for your convenience.
> 
> How can I create a dedicated region mapper for each of the new tasks? Or
> is it better to just map the old region mapper to the new tasks? I've found
> > l4_task_map(task_cap, L4RE_THIS_TASK_CAP, ... )
> but I didn't come along with the third and fourth parameter.

Generally, you cannot just use the RM of your program for the new task.
Your RM knows how to page your program but not the task you created.
However, you're not actually starting a new program but rather just
start a new thread in a new task from within the same binary. So your
RM can page both.

And indeed, you need to map the cap to the new task.

   l4_task_map(task_cap, L4RE_THIS_TASK_CAP,
               l4_obj_fpage(l4re_env()->rm, 0, L4_FPAGE_RO),
	       l4_map_obj_control(l4re_env()->rm, L4_MAP_ITEM_MAP));

> #define THREAD_MAX_NUM 20
> 
> typedef struct Edf_thread
> {
>   unsigned     dl;       // Deadline
>   void        *func;     // EIP
>   l4_cap_idx_t cap;      // L4 Capability
> } Edf_thread;
> 
> Edf_thread     thread[THREAD_MAX_NUM];
> unsigned char *thread_stack[THREAD_MAX_NUM];
> 
> unsigned       count = 0;
> 
> int create_l4_thread(Edf_thread *_thread)
> {
>   l4_msgtag_t tag;
> 
>   // Create a new task for each thread
>   l4_cap_idx_t task_cap = l4re_util_cap_alloc();
>   if (l4_is_invalid_cap(task_cap))
>     return -1;
>   l4_fpage_t task_fpage = l4_fpage(l4re_env()->first_free_utcb, 12, L4_CAP_FPAGE_RW);
>   l4_factory_create_task(l4re_env()->factory, task_cap, task_fpage);
>   //
> 
>   _thread->cap = l4re_util_cap_alloc();
>   thread[count] = *_thread;
>   thread_stack[count] = malloc(8 << 10);
> 
>   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();
> 
>   /*
>    * Of course, using the region mapper and exception handler of the current task for the newly created task fails.
>    * I'm getting the following kernel output:
>    * > KERNEL: Warning: CPU0: Pager of 26 is invalid (pfa=010002c0, errorcode=00000004) to 3 (pc=10002c0)
>    * But how can I create a new region mapper?
>    * Or is it better to just map the old one to the new task? l4_task_map(task_cap, L4RE_THIS_TASK_CAP, ... ?)
>    */
>   l4_thread_control_pager(l4re_env()->rm);       // fails
>   l4_thread_control_exc_handler(l4re_env()->rm); // fails
> 
>   l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb,
>                           task_cap);
>   tag = l4_thread_control_commit(_thread->cap);
>   if (l4_error(tag))
>     return -2;
> 
>   tag = l4_thread_ex_regs(_thread->cap,
>                           (l4_umword_t)_thread->func,
>                           (l4_umword_t)(thread_stack[count] + sizeof(thread_stack[count])), 0);
>   if (l4_error(tag))
>     return -3;
> 
>   // Pass the deadline of the thread to the L4 system
>   l4_sched_param_t sp = l4_sched_param_by_type(Deadline, thread[count].dl, 0);
>   // Let the L4 system tell the kernel to enqueue the thread in its (deadline-based) ready queue
>   tag = l4_scheduler_run_thread(l4re_env()->scheduler, thread[count].cap, &sp);
>   if (l4_error(tag))
>     return -4;
> 
>   // Shift first_free_utcb for further threads
>   l4re_env()->first_free_utcb = (l4_addr_t)l4re_env()->first_free_utcb + L4_UTCB_OFFSET;
> 
>   return count++;
> }



Adam
-- 
Adam                 adam at os.inf.tu-dresden.de
  Lackorzynski         http://os.inf.tu-dresden.de/~adam/



More information about the l4-hackers mailing list