]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/kthread.c
cce9ff53bf993d1632e2f60112294f37485f094e
[lincan.git] / lincan / src / kthread.c
1 #include <linux/config.h>
2 #include <linux/version.h>
3
4 #if defined(MODVERSIONS)
5 #include <linux/modversions.h>
6 #endif
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9
10 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
11   #include <linux/tqueue.h>
12 #else
13   #include <linux/devfs_fs_kernel.h>
14 #endif
15
16 #include <linux/wait.h>
17 #include <linux/signal.h>
18 #include <linux/interrupt.h>
19
20
21 #include <asm/semaphore.h>
22 #include <linux/smp_lock.h>
23
24 #include "../include/kthread.h"
25
26 /* private functions */
27 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
28 static void kthread_launcher(void *data)
29 #else
30 static void kthread_launcher(unsigned long data)
31 #endif
32 {
33   kthread_t *kthread = (kthread_t *)data;
34
35   kernel_thread((int (*)(void *))kthread->function, (void *)kthread, 0);
36 }
37
38 /* public functions */
39
40 /* create a new kernel thread. Called by the creator. */
41 void start_kthread(void (*func)(kthread_t *), kthread_t *kthread)
42 {
43     /* initialize the semaphore:
44        we start with the semaphore locked. The new kernel
45        thread will setup its stuff and unlock it. This
46        control flow (the one that creates the thread) blocks
47        in the down operation below until the thread has reached
48        the up() operation.
49     */
50     sema_init(&kthread->startstop_sem, 0);
51
52     /* store the function to be executed in the data passed to
53        the launcher */
54     kthread->function=func;
55
56     /* create the new thread my running a task through keventd */
57
58 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
59
60     /* initialize the task queue structure */
61     kthread->tq.sync = 0;
62     INIT_LIST_HEAD(&kthread->tq.list);
63     kthread->tq.routine = kthread_launcher;
64     kthread->tq.data = kthread;
65
66     /* and schedule it for execution */
67     schedule_task(&kthread->tq);
68 #else
69     /* initialize tasklet */
70     tasklet_init(&kthread->tq, kthread_launcher, (unsigned long)kthread);
71     /* and schedule it for execution */
72     tasklet_schedule(&kthread->tq);
73 #endif
74
75     /* wait till it has reached the setup_thread routine */
76     down(&kthread->startstop_sem);
77 }
78
79 /* stop a kernel thread. Called by the removing instance */
80 void stop_kthread(kthread_t *kthread)
81 {
82     if (kthread->thread == NULL)
83     {
84         printk("stop_kthread: killing non existing thread!\n");
85         return;
86     }
87
88     /* this function needs to be protected with the big
89     kernel lock (lock_kernel()). The lock must be
90        grabbed before changing the terminate
91     flag and released after the down() call. */
92     lock_kernel();
93
94     /* initialize the semaphore. We lock it here, the
95        leave_thread call of the thread to be terminated
96        will unlock it. As soon as we see the semaphore
97        unlocked, we know that the thread has exited.
98     */
99     sema_init(&kthread->startstop_sem,0);
100
101     /* We need to do a memory barrier here to be sure that
102        the flags are visible on all CPUs. 
103     */
104     mb();
105
106     /* set flag to request thread termination */
107     kthread->terminate = 1;
108
109     /* We need to do a memory barrier here to be sure that
110        the flags are visible on all CPUs. 
111     */
112     mb();
113     kill_proc(kthread->thread->pid, SIGKILL, 1);
114
115     /* block till thread terminated */
116     down(&kthread->startstop_sem);
117
118     /* release the big kernel lock */
119     unlock_kernel();
120
121     /* now we are sure the thread is in zombie state. We
122        notify keventd to clean the process up.
123     */
124     kill_proc(2, SIGCHLD, 1);
125
126 }
127
128 /* initialize new created thread. Called by the new thread. */
129 void init_kthread(kthread_t *kthread, char *name)
130 {
131     /* fill in thread structure */
132     kthread->thread = current;
133
134     /* initialise termination flag */
135     kthread->terminate = 0;
136
137     /* initialise wait queue */
138     init_waitqueue_head(&kthread->queue);
139
140 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40))
141     /* lock the kernel. A new kernel thread starts without
142       the big kernel lock, regardless of the lock state
143       of the creator (the lock level is *not* inheritated)
144     */
145     lock_kernel();
146 /*    daemonize(); */
147
148     /* set signal mask to what we want to respond */
149     siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
150
151     /* set name of this process (max 15 chars + 0 !) */
152     sprintf(current->comm, name);
153
154     /* let others run */
155     unlock_kernel();
156 #else
157
158     daemonize(name);
159 #endif
160
161     /* tell the creator that we are ready and let him continue */
162     up(&kthread->startstop_sem);
163 }
164
165 /* cleanup of thread. Called by the exiting thread. */
166 void exit_kthread(kthread_t *kthread)
167 {
168     /* we are terminating */
169
170     /* lock the kernel, the exit will unlock it */
171     lock_kernel();
172     kthread->thread = NULL;
173     mb();
174
175     /* notify the stop_kthread() routine that we are terminating. */
176     up(&kthread->startstop_sem);
177     /* the kernel_thread that called clone() does a do_exit here. */
178
179     /* there is no race here between execution of the "killer" and real termination
180        of the thread (race window between up and do_exit), since both the
181        thread and the "killer" function are running with the kernel lock held.
182        The kernel lock will be freed after the thread exited, so the code
183        is really not executed anymore as soon as the unload functions gets
184        the kernel lock back.
185        The init process may not have made the cleanup of the process here,
186        but the cleanup can be done safely with the module unloaded.
187     */
188
189 }
190