Hi everyone,
I'm not sure if I'm at the right place to ask this question, but I
might aswell try; I'm writing you this mail because there is one thing
I can't understand in the openbsd kthread.
Actually, it is those two functions from the kthread's man :
kthread_create and kthread_create_deferred.. from man 9
kthread_create creates a kernel thread and kthread_create_deferred
adds a pointer to a function in a queue that will be then went through
and each of it's elements will be launched in a seperate kthread.
I wrote a simple syscall using the lkm and kthread_create;
Here is the syscall :
#include sys/param.h
#include sys/kthread.h
#include sys/types.h
#include sys/malloc.h
#define NB_THREAD 1
voidtheHook(void *data)
{
uprintf(Goodbye threaded world\n);
kthread_exit(0);
}
int mycall(struct proc *p, void *uap, int retval[])
{
int error;
struct proc *mypr;
uprintf( I create a new thread for fun :)\n );
kthread_create(theHook, NULL, mypr, bite!);
return (0);
}
But it would not work : The thread was not launched.
I therefor replaced kthread_create by kthread_create_deferred and it
looked like this :
kthread_create_deferred(theHook, NULL)
And then the thread was launched ...
This was disturbing me, so I went and looked at the kernel sources for
the threads :
/usr/src/sys/kern/kern_kthread.c
/usr/src/sys/sys/kthread.h
In kthread_create, everything seems normal, it creates a process.
But in kthread_create_deferred i found this code :
kthread_create_deferred(void (*func)(void *), void *arg)
{
struct kthread_q *kq;
if (kthread_create_now) {
(*func)(arg);
return;
}
kq = malloc(sizeof *kq, M_TEMP, M_NOWAIT);
if (kq == NULL)
panic(unable to allocate kthread_q);
bzero(kq, sizeof *kq);
kq-kq_func = func;
kq-kq_arg = arg;
SIMPLEQ_INSERT_TAIL(kthread_q, kq, kq_q);
}
What this code roughly does is :
Check if the variable kthread_create_now is true,
if it is, it launchs the function sent in parameter
else it adds it in the queue with it's attached parameters
So I ask myself :When is initialised this kthread_create_now variable ?
And I found out that it is global, and never initialized. It is also
used in the next function : kthread_run_deferred_queue :
kthread_run_deferred_queue(void)
{
struct kthread_q *kq;
/* No longer need to defer kthread creation. */
kthread_create_now = 1;
while ((kq = SIMPLEQ_FIRST(kthread_q)) != NULL) {
SIMPLEQ_REMOVE_HEAD(kthread_q, kq_q);
(*kq-kq_func)(kq-kq_arg);
free(kq, M_TEMP);
}
}
it sets ouyr mysterious variable to 1 and then launch every function
in the queu one by one. I can't find in any of those functions a hint
of a thread.
i try searching where kthread_run_deffered_queue is called, maybe
there is where the threads are launched ?
After a grep over all the sources, I can find only one call in the
file kern/init_main.c line 426 and still no clue where those threads
are launched.
I just can't figure out how it works ?!
With a simple kthread_create, it won't work ... Am I using it the rigth way ?
is it normal and safe that the global variable kthread_create_now is
not initialised ?
Is it normal that kthread_create_deferred doesn't launch any threads
or am I just not understanding the sources ?
Thanks a lot,
--
Gallon sylvestre
Astek michant / Assistant CISCO
Rathaxes Core Developper
http://blog.evilkittens.org/~syl/