]>
Commit | Line | Data |
---|---|---|
f1b59d26 | 1 | #include <splat-ctl.h> |
f1ca4da6 | 2 | |
3 | #define KZT_SUBSYSTEM_THREAD 0x0600 | |
4 | #define KZT_THREAD_NAME "thread" | |
5 | #define KZT_THREAD_DESC "Kernel Thread Tests" | |
6 | ||
7 | #define KZT_THREAD_TEST1_ID 0x0601 | |
8 | #define KZT_THREAD_TEST1_NAME "create" | |
9 | #define KZT_THREAD_TEST1_DESC "Validate thread creation and destruction" | |
10 | ||
11 | #define KZT_THREAD_TEST_MAGIC 0x4488CC00UL | |
12 | ||
13 | typedef struct thread_priv { | |
14 | unsigned long tp_magic; | |
15 | struct file *tp_file; | |
16 | spinlock_t tp_lock; | |
17 | wait_queue_head_t tp_waitq; | |
18 | int tp_rc; | |
19 | } thread_priv_t; | |
20 | ||
21 | ||
22 | static void | |
23 | kzt_thread_work(void *priv) | |
24 | { | |
25 | thread_priv_t *tp = (thread_priv_t *)priv; | |
26 | ||
27 | spin_lock(&tp->tp_lock); | |
28 | ASSERT(tp->tp_magic == KZT_THREAD_TEST_MAGIC); | |
29 | tp->tp_rc = 1; | |
30 | ||
31 | spin_unlock(&tp->tp_lock); | |
32 | wake_up(&tp->tp_waitq); | |
33 | ||
34 | thread_exit(); | |
35 | } | |
36 | ||
37 | static int | |
38 | kzt_thread_test1(struct file *file, void *arg) | |
39 | { | |
40 | thread_priv_t tp; | |
41 | DEFINE_WAIT(wait); | |
42 | kthread_t *thr; | |
43 | int rc = 0; | |
44 | ||
45 | tp.tp_magic = KZT_THREAD_TEST_MAGIC; | |
46 | tp.tp_file = file; | |
47 | spin_lock_init(&tp.tp_lock); | |
48 | init_waitqueue_head(&tp.tp_waitq); | |
49 | tp.tp_rc = 0; | |
50 | ||
51 | spin_lock(&tp.tp_lock); | |
52 | ||
53 | thr = (kthread_t *)thread_create(NULL, 0, kzt_thread_work, &tp, 0, | |
54 | (proc_t *) &p0, TS_RUN, minclsyspri); | |
55 | /* Must never fail under Solaris, but we check anyway so we can | |
56 | * report an error when this impossible thing happens */ | |
57 | if (thr == NULL) { | |
58 | rc = -ESRCH; | |
59 | goto out; | |
60 | } | |
61 | ||
62 | for (;;) { | |
63 | prepare_to_wait(&tp.tp_waitq, &wait, TASK_UNINTERRUPTIBLE); | |
64 | if (tp.tp_rc) | |
65 | break; | |
66 | ||
67 | spin_unlock(&tp.tp_lock); | |
68 | schedule(); | |
69 | spin_lock(&tp.tp_lock); | |
70 | } | |
71 | ||
72 | kzt_vprint(file, KZT_THREAD_TEST1_NAME, "%s", | |
73 | "Thread successfully started and exited cleanly\n"); | |
74 | out: | |
75 | spin_unlock(&tp.tp_lock); | |
76 | ||
77 | return rc; | |
78 | } | |
79 | ||
80 | kzt_subsystem_t * | |
81 | kzt_thread_init(void) | |
82 | { | |
83 | kzt_subsystem_t *sub; | |
84 | ||
85 | sub = kmalloc(sizeof(*sub), GFP_KERNEL); | |
86 | if (sub == NULL) | |
87 | return NULL; | |
88 | ||
89 | memset(sub, 0, sizeof(*sub)); | |
90 | strncpy(sub->desc.name, KZT_THREAD_NAME, KZT_NAME_SIZE); | |
91 | strncpy(sub->desc.desc, KZT_THREAD_DESC, KZT_DESC_SIZE); | |
92 | INIT_LIST_HEAD(&sub->subsystem_list); | |
93 | INIT_LIST_HEAD(&sub->test_list); | |
94 | spin_lock_init(&sub->test_lock); | |
95 | sub->desc.id = KZT_SUBSYSTEM_THREAD; | |
96 | ||
97 | KZT_TEST_INIT(sub, KZT_THREAD_TEST1_NAME, KZT_THREAD_TEST1_DESC, | |
98 | KZT_THREAD_TEST1_ID, kzt_thread_test1); | |
99 | ||
100 | return sub; | |
101 | } | |
102 | ||
103 | void | |
104 | kzt_thread_fini(kzt_subsystem_t *sub) | |
105 | { | |
106 | ASSERT(sub); | |
107 | KZT_TEST_FINI(sub, KZT_THREAD_TEST1_ID); | |
108 | ||
109 | kfree(sub); | |
110 | } | |
111 | ||
112 | int | |
113 | kzt_thread_id(void) { | |
114 | return KZT_SUBSYSTEM_THREAD; | |
115 | } |