1 /*-
2  * Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 #ifndef _LINUX_THREAD_H_
27 #define	_LINUX_THREAD_H_
28 
29 #define	MUTEX_NO_OWNER ((pthread_t)-1UL)
30 
31 typedef struct task_struct {
32 	const char *comm;
33 	pid_t	pid;
34 } task_struct_t;
35 
36 typedef struct wait_queue {
37 } wait_queue_t;
38 
39 #define	DEFINE_WAIT(name) wait_queue_t name = {}
40 
41 typedef struct wait_queue_head {
42 	int	sleep_ref;
43 	int	sleep_count;
44 	int	do_selwakeup;
45 } wait_queue_head_t;
46 
47 #define	DECLARE_WAIT_QUEUE_HEAD(name) \
48 	struct wait_queue_head name = { 0, 0 }
49 
50 typedef struct semaphore {
51 	int32_t	value;
52 	pthread_t owner;
53 } semaphore_t;
54 
55 #define	DEFINE_SPINLOCK(n) struct spinlock n = { }
56 #define	DEFINE_MUTEX(n) struct mutex n = { .sem.value = 1, .sem.owner = MUTEX_NO_OWNER, }
57 struct mutex {
58 	struct semaphore sem;
59 };
60 
61 typedef struct completion {
62 	uint32_t done;
63 	wait_queue_head_t wait;
64 } completion_t;
65 
66 uint32_t atomic_drop(void);
67 void	atomic_pickup(uint32_t);
68 void	init_waitqueue_head(wait_queue_head_t *q);
69 void	uninit_waitqueue_head(wait_queue_head_t *q);
70 void	interruptible_sleep_on(wait_queue_head_t *q);
71 uint64_t interruptible_sleep_on_timeout(wait_queue_head_t *q, uint64_t timeout);
72 int	waitqueue_active(wait_queue_head_t *q);
73 
74 void	wake_up(wait_queue_head_t *q);
75 void	wake_up_all(wait_queue_head_t *q);
76 void	wake_up_nr(wait_queue_head_t *q, uint32_t nr);
77 void	__wait_event(wait_queue_head_t *q);
78 int	__wait_event_timed(wait_queue_head_t *q, struct timespec *ts);
79 void	__wait_get_timeout(uint64_t timeout, struct timespec *ts);
80 
81 void	add_wait_queue(wait_queue_head_t *, wait_queue_t *);
82 void	remove_wait_queue(wait_queue_head_t *, wait_queue_t *);
83 int	schedule_timeout(long);
84 int	schedule_timeout_interruptible(long);
85 void	schedule(void);
86 
87 #define	wake_up_poll(q,f)               wake_up(q)
88 #define	wake_up_interruptible(q)        wake_up(q)
89 #define	wake_up_interruptible_poll(q,f) wake_up(q)
90 #define	wake_up_interruptible_nr(q, nr) wake_up_nr(q,nr)
91 #define	wake_up_interruptible_all(q)    wake_up_all(q)
92 #define	wake_up_interruptible_sync(q)   wake_up(q)
93 
94 typedef int wait_on_bit_fn_t (void *);
95 
96 int	wait_on_bit_action(void *, int, wait_on_bit_fn_t *, unsigned);
97 int	wait_on_bit(void *, int, unsigned);
98 void	wake_up_bit(void *, int);
99 
100 #define	wait_event(wq, condition)		\
101 do {						\
102 	atomic_lock();				\
103 	while (!(condition))			\
104 		__wait_event(&(wq));		\
105 	atomic_unlock();			\
106 } while (0)
107 
108 #define	wait_event_interruptible_exclusive(wq,condition) \
109 	wait_event_interruptible(wq,condition)
110 
111 #define	wait_event_interruptible(wq, condition)	\
112 ({						\
113 	int __ret = 0;				\
114 	atomic_lock();				\
115 	while (!(condition)) {			\
116 	  if (check_signal()) {		\
117 		__ret = -ERESTARTSYS;		\
118 		break;				\
119 	  }					\
120 	  __wait_event(&(wq));			\
121 	}					\
122 	atomic_unlock();			\
123 	__ret;					\
124 })
125 
126 #define	wait_event_timeout(wq, condition, timeout)	\
127 ({							\
128 	struct timespec ts[2];				\
129 	long __ret = timeout;				\
130 	__wait_get_timeout(__ret, ts);			\
131 	atomic_lock();					\
132 	while (!(condition)) {				\
133 	  if (__wait_event_timed(&(wq), ts)) {		\
134 		__ret = 0;				\
135 		break;					\
136 	  }						\
137 	}						\
138 	atomic_unlock();				\
139 	__ret;						\
140 })
141 
142 #define	wait_event_interruptible_timeout(wq, condition, timeout) \
143 ({							\
144 	struct timespec ts[2];				\
145 	long __ret = timeout;				\
146 	__wait_get_timeout(__ret, ts);			\
147 	atomic_lock();					\
148 	while (!(condition)) {				\
149 	  if (check_signal()) {			\
150 		__ret = -ERESTARTSYS;			\
151 		break;					\
152 	  }						\
153 	  if (__wait_event_timed(&(wq), ts)) {		\
154 		__ret = 0;				\
155 		break;					\
156 	  }						\
157 	}						\
158 	atomic_unlock();				\
159 	__ret;						\
160 })
161 
162 #define	DECLARE_WAITQUEUE(name, thread) \
163 	wait_queue_t name = { }
164 
165 void	sema_init(struct semaphore *, int32_t val);
166 void	sema_uninit(struct semaphore *sem);
167 
168 void	up (struct semaphore *);
169 void	down(struct semaphore *);
170 int	down_read_trylock(struct semaphore *sem);
171 int	down_trylock(struct semaphore *sem);
172 void	poll_wait(struct file *filp, wait_queue_head_t *wq, poll_table * p);
173 
174 void	mutex_lock(struct mutex *m);
175 int	mutex_lock_killable(struct mutex *m);
176 int	mutex_trylock(struct mutex *m);
177 void	mutex_unlock(struct mutex *m);
178 
179 #define	mutex_init(m) sema_init(&(m)->sem, 1)
180 #define	mutex_destroy(m) sema_uninit(&(m)->sem)
181 #define	mutex_lock_interruptible(m) (mutex_lock(m),0)
182 #define	mutex_is_locked(x) ({			\
183     int __ret;					\
184     atomic_lock();				\
185     __ret = ((x)->sem.owner != MUTEX_NO_OWNER);	\
186     atomic_unlock();				\
187     __ret;})
188 #define	init_MUTEX(s) sema_init(s,1)
189 #define	init_MUTEX_LOCKED(s) sema_init(s, 0)
190 #define	down_interruptible(x) (down(x),0)
191 
192 #define	wait_for_completion_killable(x) wait_for_completion_interruptible(x)
193 
194 void	init_completion(struct completion *x);
195 
196 #define	INIT_COMPLETION(x) \
197     init_completion(&(x))
198 #define	reinit_completion(x) \
199     init_completion(x)
200 
201 void	uninit_completion(struct completion *x);
202 void	wait_for_completion(struct completion *x);
203 uint64_t wait_for_completion_timeout(struct completion *x, uint64_t);
204 int	wait_for_completion_interruptible(struct completion *x);
205 int64_t	wait_for_completion_interruptible_timeout(struct completion *, uint64_t);
206 
207 #define	complete_all(x)	complete(x)
208 void	complete(struct completion *x);
209 
210 void	wake_up_process(struct task_struct *task);
211 
212 #define	current (&linux_task)
213 
214 typedef int (threadfn_t)(void *data);
215 struct task_struct *kthread_create(threadfn_t *func, void *data, char *fmt,...);
216 struct task_struct *kthread_run(threadfn_t *func, void *data, char *fmt,...);
217 int	kthread_stop(struct task_struct *k);
218 int	kthread_should_stop(void);
219 
220 int	try_to_freeze(void);
221 int	freezing(struct task_struct *p);
222 void	set_freezable(void);
223 
224 void	atomic_lock(void);
225 void	atomic_unlock(void);
226 pthread_mutex_t *atomic_get_lock();
227 void	atomic_pre_sleep(void);
228 void	atomic_post_sleep(void);
229 
230 int	thread_init(void);
231 int	thread_got_stopping(void);
232 
233 void	prepare_to_wait(wait_queue_head_t *, wait_queue_t *, int);
234 void	finish_wait(wait_queue_head_t *, wait_queue_t *);
235 
236 extern struct task_struct linux_task;
237 
238 int	check_signal(void);
239 void	wake_up_all_internal(void);
240 void	poll_wakeup_internal(void);
241 
242 /*
243  * RT-mutex variant
244  */
245 #define	rt_mutex mutex
246 #define	rt_mutex_init(x) mutex_init(x)
247 #define	rt_mutex_destroy(x) mutex_destroy(x)
248 #define	rt_mutex_lock(x) mutex_lock(x)
249 #define	rt_mutex_trylock(x) mutex_trylock(x)
250 #define	rt_mutex_unlock(x) mutex_unlock(x)
251 #define	DEFINE_RT_MUTEX(x) DEFINE_MUTEX(x)
252 #define	rt_mutex_is_locked(x) mutex_is_locked(x)
253 
254 #endif					/* _LINUX_THREAD_H_ */
255