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