<< Back to Writing Codezero Applications
Pagers are responsible for creating, destroying and managing the execution of threads that they are associated with. As a general rule, each pager is responsible for the set of all threads inside a particular container.
Threads may be created in an existing address space, on a brand new, clean address space, or an address space that has been created as a copy of an existing address space.
Below are example code snippets that achieve various thread manipulation operations.
/* Create a new thread in a new address space */ void thread_new(void) { struct task_ids ids; int err; ids.tid = TASK_ID_INVALID; ids.spid = TASK_ID_INVALID; ids.tgid = TASK_ID_INVALID; if ((err = l4_thread_control(THREAD_CREATE | THREAD_NEW_SPACE, &ids)) < 0) { printf("l4_thread_control failed: %d\n", err); } }
/* Create a new thread in an existing address space */ void thread_new(struct task_ids *parent) { struct task_ids ids; int err; /* Specify parent ids */ ids.tid = parent->tid; ids.spid = parent->spid; ids.tgid = TASK_ID_INVALID; if ((err = l4_thread_control(THREAD_CREATE | THREAD_SAME_SPACE, &ids)) < 0) { printf("l4_thread_control failed: %d\n", err); } }
/* Create a new thread in a new, copied space */ void thread_new(struct task_ids *parent) { struct task_ids ids; int err; /* Specify parent ids */ ids.tid = parent->tid; ids.spid = parent->spid; ids.tgid = TASK_ID_INVALID; if ((err = l4_thread_control(THREAD_CREATE | THREAD_COPY_SPACE, &ids)) < 0) { printf("l4_thread_control failed: %d\n", err); } }
void thread_manipulate(struct task_ids *new_ids, unsigned long new_stack, unsigned long utcb_address) { struct exregs_data exregs; int err; memset(&exregs, 0, sizeof(exregs)); /* Set new stack for child */ exregs_set_stack(&exregs, new_stack); /* Set child return value to 0 */ exregs_set_mr(&exregs, MR_RETURN, 0); /* Set child utcb */ exregs_set_utcb(&exregs, utcb_address); /* Do the actual exchange registers call to microkernel */ if ((err = l4_exchange_registers(&exregs, new_ids->tid)) < 0) printf("Exchange registers error: %d\n", err); }
Note, that l4_thread_control and l4_exchange_registers() are privileged system calls that may only be executed by pagers. In that respect, the operational model in the above system calls are as follows:
In conclusion, the above code snippets are used usually as part of an IPC request/reply pair between the pager on the system and its client.