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