With a little macro ugliness, we can make kthread_create() and
kthread_run() typesafe: avoid the casts to and from void *.  To do
this we use a temporary function pointer which takes the type of the
data as a callback: if the function doesn't match, we get:

        warning: initialization from incompatible pointer type

It's actually slightly over-strict, since a void * would be compatible
with any function type, but there's only one such case in the kernel
anyway.

Signed-off-by: Rusty Russell <[EMAIL PROTECTED]>
---
 include/linux/kthread.h |   30 +++++++++++++++++++++++++++---
 kernel/kthread.c        |   29 +++++------------------------
 2 files changed, 32 insertions(+), 27 deletions(-)

diff -r 110aa94129d0 include/linux/kthread.h
--- a/include/linux/kthread.h   Fri Jan 18 10:32:31 2008 +1100
+++ b/include/linux/kthread.h   Fri Jan 18 11:31:49 2008 +1100
@@ -4,9 +4,33 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 
-struct task_struct *kthread_create(int (*threadfn)(void *data),
-                                  void *data,
-                                  const char namefmt[], ...);
+/**
+ * kthread_create - create a kthread.
+ * @threadfn: the function to run until signal_pending(current).
+ * @data: data ptr for @threadfn.
+ * @namefmt: printf-style name for the thread.
+ *
+ * Description: This helper function creates and names a kernel
+ * thread.  The thread will be stopped: use wake_up_process() to start
+ * it.  See also kthread_run(), kthread_create_on_cpu().
+ *
+ * When woken, the thread will run @threadfn() with @data as its
+ * argument. @threadfn() can either call do_exit() directly if it is a
+ * standalone thread for which noone will call kthread_stop(), or
+ * return when 'kthread_should_stop()' is true (which means
+ * kthread_stop() has been called).  The return value should be zero
+ * or a negative error number; it will be passed to kthread_stop().
+ *
+ * Returns a task_struct or ERR_PTR(-ENOMEM).
+ */
+#define kthread_create(threadfn, data, namefmt...) ({          \
+       int (*_threadfn)(typeof(data)) = (threadfn);            \
+       __kthread_create((void *)_threadfn, (data), namefmt);   \
+})
+
+struct task_struct *__kthread_create(int (*threadfn)(void *data),
+                                    void *data,
+                                    const char namefmt[], ...);
 
 /**
  * kthread_run - create and wake a thread.
diff -r 110aa94129d0 kernel/kthread.c
--- a/kernel/kthread.c  Fri Jan 18 10:32:31 2008 +1100
+++ b/kernel/kthread.c  Fri Jan 18 11:31:49 2008 +1100
@@ -102,29 +102,10 @@ static void create_kthread(struct kthrea
        complete(&create->done);
 }
 
-/**
- * kthread_create - create a kthread.
- * @threadfn: the function to run until signal_pending(current).
- * @data: data ptr for @threadfn.
- * @namefmt: printf-style name for the thread.
- *
- * Description: This helper function creates and names a kernel
- * thread.  The thread will be stopped: use wake_up_process() to start
- * it.  See also kthread_run(), kthread_create_on_cpu().
- *
- * When woken, the thread will run @threadfn() with @data as its
- * argument. @threadfn() can either call do_exit() directly if it is a
- * standalone thread for which noone will call kthread_stop(), or
- * return when 'kthread_should_stop()' is true (which means
- * kthread_stop() has been called).  The return value should be zero
- * or a negative error number; it will be passed to kthread_stop().
- *
- * Returns a task_struct or ERR_PTR(-ENOMEM).
- */
-struct task_struct *kthread_create(int (*threadfn)(void *data),
-                                  void *data,
-                                  const char namefmt[],
-                                  ...)
+struct task_struct *__kthread_create(int (*threadfn)(void *data),
+                                    void *data,
+                                    const char namefmt[],
+                                    ...)
 {
        struct kthread_create_info create;
 
@@ -149,7 +130,7 @@ struct task_struct *kthread_create(int (
        }
        return create.result;
 }
-EXPORT_SYMBOL(kthread_create);
+EXPORT_SYMBOL(__kthread_create);
 
 /**
  * kthread_bind - bind a just-created kthread to a cpu.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to