7,9 → 7,6 |
#include <linux/stddef.h> |
#include <linux/spinlock.h> |
#include <asm/current.h> |
|
|
|
#include <syscall.h> |
|
typedef struct __wait_queue wait_queue_t; |
16,20 → 13,89 |
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key); |
int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key); |
|
typedef struct __wait_queue_head wait_queue_head_t; |
/* __wait_queue::flags */ |
#define WQ_FLAG_EXCLUSIVE 0x01 |
#define WQ_FLAG_WOKEN 0x02 |
|
struct __wait_queue |
{ |
struct __wait_queue { |
unsigned int flags; |
void *private; |
wait_queue_func_t func; |
struct list_head task_list; |
evhandle_t evnt; |
}; |
|
struct __wait_queue_head |
{ |
struct wait_bit_key { |
void *flags; |
int bit_nr; |
#define WAIT_ATOMIC_T_BIT_NR -1 |
unsigned long timeout; |
}; |
|
struct wait_bit_queue { |
struct wait_bit_key key; |
wait_queue_t wait; |
}; |
|
struct __wait_queue_head { |
spinlock_t lock; |
struct list_head task_list; |
}; |
typedef struct __wait_queue_head wait_queue_head_t; |
|
struct task_struct; |
|
/* |
* Macros for declaration and initialisaton of the datatypes |
*/ |
|
#define __WAITQUEUE_INITIALIZER(name, tsk) { \ |
.private = tsk, \ |
.func = default_wake_function, \ |
.task_list = { NULL, NULL } } |
|
#define DECLARE_WAITQUEUE(name, tsk) \ |
wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) |
|
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ |
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \ |
.task_list = { &(name).task_list, &(name).task_list } } |
|
#define DECLARE_WAIT_QUEUE_HEAD(name) \ |
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) |
|
#define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ |
{ .flags = word, .bit_nr = bit, } |
|
#define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \ |
{ .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, } |
|
extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *); |
|
#ifdef CONFIG_LOCKDEP |
# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \ |
({ init_waitqueue_head(&name); name; }) |
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \ |
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) |
#else |
# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name) |
#endif |
|
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p) |
{ |
q->flags = 0; |
q->private = p; |
q->func = default_wake_function; |
} |
|
static inline void |
init_waitqueue_func_entry(wait_queue_t *q, wait_queue_func_t func) |
{ |
q->flags = 0; |
q->private = NULL; |
q->func = func; |
} |
|
static inline int waitqueue_active(wait_queue_head_t *q) |
{ |
return !list_empty(&q->task_list); |
45,6 → 111,53 |
} |
|
/* |
* Used for wake-one threads: |
*/ |
static inline void |
__add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait) |
{ |
wait->flags |= WQ_FLAG_EXCLUSIVE; |
__add_wait_queue(q, wait); |
} |
|
static inline void __add_wait_queue_tail(wait_queue_head_t *head, |
wait_queue_t *new) |
{ |
list_add_tail(&new->task_list, &head->task_list); |
} |
|
static inline void |
__add_wait_queue_tail_exclusive(wait_queue_head_t *q, wait_queue_t *wait) |
{ |
wait->flags |= WQ_FLAG_EXCLUSIVE; |
__add_wait_queue_tail(q, wait); |
} |
|
static inline void |
__remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old) |
{ |
list_del(&old->task_list); |
} |
|
typedef int wait_bit_action_f(struct wait_bit_key *, int mode); |
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); |
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key); |
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key); |
void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr); |
void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); |
void __wake_up_bit(wait_queue_head_t *, void *, int); |
int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned); |
int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned); |
void wake_up_bit(void *, int); |
void wake_up_atomic_t(atomic_t *); |
int out_of_line_wait_on_bit(void *, int, wait_bit_action_f *, unsigned); |
int out_of_line_wait_on_bit_timeout(void *, int, wait_bit_action_f *, unsigned, unsigned long); |
int out_of_line_wait_on_bit_lock(void *, int, wait_bit_action_f *, unsigned); |
int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned); |
wait_queue_head_t *bit_waitqueue(void *, int); |
|
/* |
|
#define __wait_event(wq, condition) \ |
do { \ |
DEFINE_WAIT(__wait); \ |
128,8 → 241,41 |
__ret; \ |
}) |
|
static inline |
void wake_up(wait_queue_head_t *q) |
{ |
wait_queue_t *curr; |
unsigned long flags; |
|
spin_lock_irqsave(&q->lock, flags); |
curr = list_first_entry(&q->task_list, typeof(*curr), task_list); |
{ |
// printf("raise event \n"); |
kevent_t event; |
event.code = -1; |
RaiseEvent(curr->evnt, 0, &event); |
} |
spin_unlock_irqrestore(&q->lock, flags); |
} |
|
static inline |
void wake_up_interruptible(wait_queue_head_t *q) |
{ |
wait_queue_t *curr; |
unsigned long flags; |
|
spin_lock_irqsave(&q->lock, flags); |
curr = list_first_entry(&q->task_list, typeof(*curr), task_list); |
{ |
// printf("raise event \n"); |
kevent_t event; |
event.code = -1; |
RaiseEvent(curr->evnt, 0, &event); |
} |
spin_unlock_irqrestore(&q->lock, flags); |
} |
|
static inline |
void wake_up_all(wait_queue_head_t *q) |
{ |
wait_queue_t *curr; |
139,7 → 285,6 |
list_for_each_entry(curr, &q->task_list, task_list) |
{ |
// printf("raise event \n"); |
|
kevent_t event; |
event.code = -1; |
RaiseEvent(curr->evnt, 0, &event); |