Linux wait_queue_entry_t 实现 生产和消费
关键代码
关键头文件结构体
#include <linux/wait.h>
#include <linux/spinlock.h>
#define BUFFER_SIZE 100
struct buffer {
int data[BUFFER_SIZE];
int count;
int head;
int tail;
wait_queue_head_t not_empty;
wait_queue_head_t not_full;
spinlock_t lock;
};
struct buffer my_buffer;
void init_buffer(struct buffer *buf) {
buf->head = buf->tail = 0;
buf->count = 0;
spin_lock_init(&buf->lock);
init_waitqueue_head(&buf->not_empty);
init_waitqueue_head(&buf->not_full);
}
生产者函数
void producer(struct buffer *buf, int value) {
unsigned long flags;
wait_queue_entry_t wait;
spin_lock_irqsave(&buf->lock, flags);
while (buf->count == BUFFER_SIZE) {
init_waitqueue_entry(&wait, current);
add_wait_queue(&buf->not_full, &wait);
spin_unlock_irqrestore(&buf->lock, flags);
schedule();
spin_lock_irqsave(&buf->lock, flags);
remove_wait_queue(&buf->not_full, &wait);
}
buf->data[buf->tail] = value;
buf->tail = buf->tail + 1;
buf->count++;
wake_up(&buf->not_empty);
spin_unlock_irqrestore(&buf->lock, flags);
}
消费者函数
int consumer(struct buffer *buf) {
unsigned long flags;
wait_queue_entry_t wait;
int value;
spin_lock_irqsave(&buf->lock, flags);
while (buf->count == 0) {
init_waitqueue_entry(&wait, current);
add_wait_queue(&buf->not_empty, &wait);
spin_unlock_irqrestore(&buf->lock, flags);
schedule();
spin_lock_irqsave(&buf->lock, flags);
remove_wait_queue(&buf->not_empty, &wait);
}
value = buf->data[buf->head];
buf->head = (buf->head + 1) % BUFFER_SIZE;
buf->count--;
wake_up(&buf->not_full);
spin_unlock_irqrestore(&buf->lock, flags);
return value;
}