1 | /*- |
---|
2 | * Copyright (c) 2010 Isilon Systems, Inc. |
---|
3 | * Copyright (c) 2010 iX Systems, Inc. |
---|
4 | * Copyright (c) 2010 Panasas, Inc. |
---|
5 | * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. |
---|
6 | * All rights reserved. |
---|
7 | * |
---|
8 | * Redistribution and use in source and binary forms, with or without |
---|
9 | * modification, are permitted provided that the following conditions |
---|
10 | * are met: |
---|
11 | * 1. Redistributions of source code must retain the above copyright |
---|
12 | * notice unmodified, this list of conditions, and the following |
---|
13 | * disclaimer. |
---|
14 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
15 | * notice, this list of conditions and the following disclaimer in the |
---|
16 | * documentation and/or other materials provided with the distribution. |
---|
17 | * |
---|
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
---|
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
---|
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
---|
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
---|
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
---|
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
---|
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
---|
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
---|
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
28 | * |
---|
29 | * $FreeBSD$ |
---|
30 | */ |
---|
31 | #ifndef _LINUX_KTHREAD_H_ |
---|
32 | #define _LINUX_KTHREAD_H_ |
---|
33 | |
---|
34 | #include <sys/param.h> |
---|
35 | #include <sys/lock.h> |
---|
36 | #include <sys/mutex.h> |
---|
37 | #include <sys/kernel.h> |
---|
38 | #include <sys/kthread.h> |
---|
39 | #include <sys/sleepqueue.h> |
---|
40 | |
---|
41 | #include <machine/rtems-bsd-thread.h> |
---|
42 | |
---|
43 | #include <linux/slab.h> |
---|
44 | #include <linux/sched.h> |
---|
45 | #include <linux/smp.h> |
---|
46 | #include <linux/threads.h> |
---|
47 | |
---|
48 | #define KTHREAD_LOCK(task) mtx_lock(&(task)->lock) |
---|
49 | #define KTHREAD_UNLOCK(task) mtx_unlock(&(task)->lock) |
---|
50 | |
---|
51 | static inline void |
---|
52 | _kthread_fn(void *arg) |
---|
53 | { |
---|
54 | struct task_struct *task; |
---|
55 | struct thread *c; |
---|
56 | |
---|
57 | task = arg; |
---|
58 | task_struct_set(curthread, task); |
---|
59 | c = task->task_thread; |
---|
60 | sleepq_lock(c); |
---|
61 | while (task->state == TASK_DORMANT) |
---|
62 | sleepq_wait(c, 0); |
---|
63 | sleepq_release(c); |
---|
64 | if (task->should_stop == 0) |
---|
65 | task->task_ret = task->task_fn(task->task_data); |
---|
66 | KTHREAD_LOCK(task); |
---|
67 | task->should_stop = TASK_STOPPED; |
---|
68 | wakeup(task); |
---|
69 | KTHREAD_UNLOCK(task); |
---|
70 | kthread_exit(); |
---|
71 | } |
---|
72 | |
---|
73 | static inline struct task_struct * |
---|
74 | _kthread_create(int (*threadfn)(void *data), void *data) |
---|
75 | { |
---|
76 | struct task_struct *task; |
---|
77 | |
---|
78 | task = kzalloc(sizeof(*task), GFP_KERNEL); |
---|
79 | task->task_fn = threadfn; |
---|
80 | task->task_data = data; |
---|
81 | mtx_init(&task->lock, "kthread", NULL, MTX_DEF); |
---|
82 | |
---|
83 | return (task); |
---|
84 | } |
---|
85 | |
---|
86 | #define kthread_create(fn, data, fmt, ...) \ |
---|
87 | ({ \ |
---|
88 | struct task_struct *_task; \ |
---|
89 | \ |
---|
90 | _task = _kthread_create((fn), (data)); \ |
---|
91 | if (kthread_add(_kthread_fn, _task, NULL, &_task->task_thread, \ |
---|
92 | 0, 0, fmt, ## __VA_ARGS__)) { \ |
---|
93 | kfree(_task); \ |
---|
94 | _task = NULL; \ |
---|
95 | } else \ |
---|
96 | task_struct_set(_task->task_thread, _task); \ |
---|
97 | _task; \ |
---|
98 | }) |
---|
99 | |
---|
100 | #define kthread_should_stop() current->should_stop |
---|
101 | |
---|
102 | static inline int |
---|
103 | kthread_stop(struct task_struct *task) |
---|
104 | { |
---|
105 | |
---|
106 | KTHREAD_LOCK(task); |
---|
107 | task->should_stop = TASK_SHOULD_STOP; |
---|
108 | wake_up_process(task); |
---|
109 | while (task->should_stop != TASK_STOPPED) |
---|
110 | msleep(task, &task->lock, PWAIT, "kstop", hz); |
---|
111 | KTHREAD_UNLOCK(task); |
---|
112 | return task->task_ret; |
---|
113 | } |
---|
114 | |
---|
115 | static inline void |
---|
116 | kthread_bind(struct task_struct *task, unsigned int cpu) |
---|
117 | { |
---|
118 | /* FIXME */ |
---|
119 | rtems_id task_id = rtems_bsd_get_task_id(task->task_thread); |
---|
120 | rtems_id sched_id; |
---|
121 | rtems_status_code sc; |
---|
122 | rtems_task_priority prio; |
---|
123 | |
---|
124 | sc = rtems_scheduler_ident(cpu, &sched_id); |
---|
125 | if (sc != RTEMS_SUCCESSFUL) |
---|
126 | panic("kthread_bind: scheduler ident"); |
---|
127 | |
---|
128 | sc = rtems_task_set_priority(task_id, RTEMS_CURRENT_PRIORITY, &prio); |
---|
129 | if (sc != RTEMS_SUCCESSFUL) |
---|
130 | panic("kthread_bind: get priority"); |
---|
131 | |
---|
132 | sc = rtems_task_set_scheduler(task_id, sched_id, prio); |
---|
133 | if (sc != RTEMS_SUCCESSFUL) |
---|
134 | panic("kthread_bind: set scheduler"); |
---|
135 | } |
---|
136 | |
---|
137 | #endif /* _LINUX_KTHREAD_H_ */ |
---|