1 #include <sys/thread.h>
6 typedef struct thread_priv_s
{
7 unsigned long tp_magic
; /* Magic */
8 void (*tp_func
)(void *); /* Registered function */
9 void *tp_args
; /* Args to be passed to function */
10 size_t tp_len
; /* Len to be passed to function */
11 int tp_state
; /* State to start thread at */
12 pri_t tp_pri
; /* Priority to start threat at */
13 volatile kthread_t
*tp_task
; /* Task pointer for new thread */
14 spinlock_t tp_lock
; /* Syncronization lock */
15 wait_queue_head_t tp_waitq
; /* Syncronization wait queue */
19 thread_generic_wrapper(void *arg
)
21 thread_priv_t
*tp
= (thread_priv_t
*)arg
;
26 /* Use the truncated function name as thread name */
27 snprintf(name
, sizeof(name
), "%s", "kthread");
30 spin_lock(&tp
->tp_lock
);
31 BUG_ON(tp
->tp_magic
!= TP_MAGIC
);
34 tp
->tp_task
= get_current();
35 set_current_state(tp
->tp_state
);
36 set_user_nice((kthread_t
*)tp
->tp_task
, PRIO_TO_NICE(tp
->tp_pri
));
38 spin_unlock(&tp
->tp_lock
);
39 wake_up(&tp
->tp_waitq
);
41 /* DO NOT USE 'ARG' AFTER THIS POINT, EVER, EVER, EVER!
42 * Local variables are used here because after the calling thread
43 * has been woken up it will exit and this memory will no longer
44 * be safe to access since it was declared on the callers stack. */
56 EXPORT_SYMBOL(__thread_exit
);
58 /* thread_create() may block forever if it cannot create a thread or
59 * allocate memory. This is preferable to returning a NULL which Solaris
60 * style callers likely never check for... since it can't fail. */
62 __thread_create(caddr_t stk
, size_t stksize
, void (*proc
)(void *),
63 void *args
, size_t len
, int *pp
, int state
, pri_t pri
)
69 /* Option pp is simply ignored */
70 /* Variable stack size unsupported */
74 /* Variable tp is located on the stack and not the heap because I want
75 * to minimize any chance of a failure, since the Solaris code is designed
76 * such that this function cannot fail. This is a little dangerous since
77 * we're passing a stack address to a new thread but correct locking was
78 * added to ensure the callee can use the data safely until wake_up(). */
79 tp
.tp_magic
= TP_MAGIC
;
86 spin_lock_init(&tp
.tp_lock
);
87 init_waitqueue_head(&tp
.tp_waitq
);
89 spin_lock(&tp
.tp_lock
);
91 /* Solaris says this must never fail so we try forever */
92 while ((pid
= kernel_thread(thread_generic_wrapper
, (void *)&tp
, 0)) < 0)
93 printk(KERN_ERR
"Unable to create thread; pid = %ld\n", pid
);
95 /* All signals are ignored due to sleeping TASK_UNINTERRUPTIBLE */
97 prepare_to_wait(&tp
.tp_waitq
, &wait
, TASK_UNINTERRUPTIBLE
);
98 if (tp
.tp_task
!= NULL
)
101 spin_unlock(&tp
.tp_lock
);
103 spin_lock(&tp
.tp_lock
);
106 /* Verify the pid retunred matches the pid in the task struct */
107 BUG_ON(pid
!= (tp
.tp_task
)->pid
);
109 spin_unlock(&tp
.tp_lock
);
111 return (kthread_t
*)tp
.tp_task
;
113 EXPORT_SYMBOL(__thread_create
);