Update the thread shim to use the current kernel threading API.
We need to use kthread_create() here for a few reasons. First off to old kernel_thread() API functioin will be going away. Secondly, and more importantly if I use kthread_create() we can then properly implement a thread_exit() function which terminates the kernel thread at any point with do_exit(). This fixes our cleanup bug which was caused by dropping a mutex twice after thread_exit() didn't really exit. git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@66 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
This commit is contained in:
parent
996faa6869
commit
968eccd1d1
|
@ -8,6 +8,7 @@ extern "C" {
|
|||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
|
@ -30,14 +31,14 @@ typedef void (*thread_func_t)(void *);
|
|||
|
||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||
__thread_create(stk, stksize, (thread_func_t)func, \
|
||||
arg, len, pp, state, pri)
|
||||
#func, arg, len, pp, state, pri)
|
||||
#define thread_exit() __thread_exit()
|
||||
#define curthread get_current()
|
||||
|
||||
extern kthread_t *__thread_create(caddr_t stk, size_t stksize,
|
||||
thread_func_t func, void *args,
|
||||
size_t len, int *pp, int state,
|
||||
pri_t pri);
|
||||
thread_func_t func, const char *name,
|
||||
void *args, size_t len, int *pp,
|
||||
int state, pri_t pri);
|
||||
extern void __thread_exit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -21,11 +21,6 @@ thread_generic_wrapper(void *arg)
|
|||
thread_priv_t *tp = (thread_priv_t *)arg;
|
||||
void (*func)(void *);
|
||||
void *args;
|
||||
char name[16];
|
||||
|
||||
/* Use the truncated function name as thread name */
|
||||
snprintf(name, sizeof(name), "%s", "kthread");
|
||||
daemonize(name);
|
||||
|
||||
spin_lock(&tp->tp_lock);
|
||||
BUG_ON(tp->tp_magic != TP_MAGIC);
|
||||
|
@ -51,6 +46,7 @@ thread_generic_wrapper(void *arg)
|
|||
void
|
||||
__thread_exit(void)
|
||||
{
|
||||
do_exit(0);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(__thread_exit);
|
||||
|
@ -60,11 +56,12 @@ EXPORT_SYMBOL(__thread_exit);
|
|||
* style callers likely never check for... since it can't fail. */
|
||||
kthread_t *
|
||||
__thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
||||
void *args, size_t len, int *pp, int state, pri_t pri)
|
||||
const char *name, void *args, size_t len, int *pp,
|
||||
int state, pri_t pri)
|
||||
{
|
||||
thread_priv_t tp;
|
||||
DEFINE_WAIT(wait);
|
||||
long pid;
|
||||
struct task_struct *tsk;
|
||||
|
||||
/* Option pp is simply ignored */
|
||||
/* Variable stack size unsupported */
|
||||
|
@ -88,9 +85,13 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
|||
|
||||
spin_lock(&tp.tp_lock);
|
||||
|
||||
/* Solaris says this must never fail so we try forever */
|
||||
while ((pid = kernel_thread(thread_generic_wrapper, (void *)&tp, 0)) < 0)
|
||||
printk(KERN_ERR "spl: Error unable to create thread; pid = %ld\n", pid);
|
||||
tsk = kthread_create(thread_generic_wrapper, (void *)&tp, "%s", name);
|
||||
if (IS_ERR(tsk)) {
|
||||
printk("spl: Failed to create thread: %ld\n", PTR_ERR(tsk));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wake_up_process(tsk);
|
||||
|
||||
/* All signals are ignored due to sleeping TASK_UNINTERRUPTIBLE */
|
||||
for (;;) {
|
||||
|
@ -103,9 +104,7 @@ __thread_create(caddr_t stk, size_t stksize, thread_func_t func,
|
|||
spin_lock(&tp.tp_lock);
|
||||
}
|
||||
|
||||
/* Verify the pid retunred matches the pid in the task struct */
|
||||
BUG_ON(pid != (tp.tp_task)->pid);
|
||||
|
||||
BUG_ON(tsk != tp.tp_task); /* Extra paranoia */
|
||||
spin_unlock(&tp.tp_lock);
|
||||
|
||||
return (kthread_t *)tp.tp_task;
|
||||
|
|
Loading…
Reference in New Issue