Skip to content

Commit

Permalink
✨ 061 数据结构循环队列
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenBaby committed Jun 22, 2022
1 parent 9cb880a commit e8459bb
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 2 deletions.
21 changes: 21 additions & 0 deletions docs/06 数据结构/061 数据结构循环队列.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 数据结构循环队列

```c++
typedef struct fifo_t
{
char *buf;
u32 length;
u32 head;
u32 tail;
} fifo_t;

void fifo_init(fifo_t *fifo, char *buf, u32 length);
bool fifo_full(fifo_t *fifo);
bool fifo_empty(fifo_t *fifo);
char fifo_get(fifo_t *fifo);
void fifo_put(fifo_t *fifo, char byte);
```
queue / fifo First in First out
生产者 - 消费者
20 changes: 20 additions & 0 deletions src/include/onix/fifo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef ONIX_FIFO_H
#define ONIX_FIFO_H

#include <onix/types.h>

typedef struct fifo_t
{
char *buf;
u32 length;
u32 head;
u32 tail;
} fifo_t;

void fifo_init(fifo_t *fifo, char *buf, u32 length);
bool fifo_full(fifo_t *fifo);
bool fifo_empty(fifo_t *fifo);
char fifo_get(fifo_t *fifo);
void fifo_put(fifo_t *fifo, char byte);

#endif
39 changes: 38 additions & 1 deletion src/kernel/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#include <onix/io.h>
#include <onix/assert.h>
#include <onix/debug.h>
#include <onix/fifo.h>
#include <onix/mutex.h>
#include <onix/task.h>

#define LOGK(fmt, args...) DEBUGK(fmt, ##args)

Expand Down Expand Up @@ -220,6 +223,13 @@ static char keymap[][4] = {
/* 0x5F */ {INV, INV, false, false}, // PrintScreen
};

static lock_t lock; // 锁
static task_t *waiter; // 等待输入的任务

#define BUFFER_SIZE 64 // 输入缓冲区大小
static char buf[BUFFER_SIZE]; // 输入缓冲区
static fifo_t fifo; // 循环队列

static bool capslock_state; // 大写锁定
static bool scrlock_state; // 滚动锁定
static bool numlock_state; // 数字锁定
Expand Down Expand Up @@ -372,7 +382,30 @@ void keyboard_handler(int vector)
if (ch == INV)
return;

LOGK("keydown %c \n", ch);
// LOGK("keydown %c \n", ch);
fifo_put(&fifo, ch);
if (waiter != NULL)
{
task_unblock(waiter);
waiter = NULL;
}
}

u32 keyboard_read(char *buf, u32 count)
{
lock_acquire(&lock);
int nr = 0;
while (nr < count)
{
while (fifo_empty(&fifo))
{
waiter = running_task();
task_block(waiter, NULL, TASK_WAITING);
}
buf[nr++] = fifo_get(&fifo);
}
lock_release(&lock);
return count;
}

void keyboard_init()
Expand All @@ -382,6 +415,10 @@ void keyboard_init()
capslock_state = false;
extcode_state = false;

fifo_init(&fifo, buf, BUFFER_SIZE);
lock_init(&lock);
waiter = NULL;

set_leds();

set_interrupt_handler(IRQ_KEYBOARD, keyboard_handler);
Expand Down
12 changes: 11 additions & 1 deletion src/kernel/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,25 @@ void idle_thread()
}
}

extern u32 keyboard_read(char *buf, u32 count);

void init_thread()
{
set_interrupt_state(true);
u32 counter = 0;

char ch;
while (true)
{
bool intr = interrupt_disable();
keyboard_read(&ch, 1);
// LOGK("%c\n", ch);
printk("%c", ch);

set_interrupt_state(intr);

// LOGK("init task %d....\n", counter++);
sleep(500);
// sleep(500);
}
}

Expand Down
44 changes: 44 additions & 0 deletions src/lib/fifo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <onix/fifo.h>
#include <onix/assert.h>

static _inline u32 fifo_next(fifo_t *fifo, u32 pos)
{
return (pos + 1) % fifo->length;
}

void fifo_init(fifo_t *fifo, char *buf, u32 length)
{
fifo->buf = buf;
fifo->length = length;
fifo->head = 0;
fifo->tail = 0;
}

bool fifo_full(fifo_t *fifo)
{
bool full = (fifo_next(fifo, fifo->head) == fifo->tail);
return full;
}

bool fifo_empty(fifo_t *fifo)
{
return (fifo->head == fifo->tail);
}

char fifo_get(fifo_t *fifo)
{
assert(!fifo_empty(fifo));
char byte = fifo->buf[fifo->tail];
fifo->tail = fifo_next(fifo, fifo->tail);
return byte;
}

void fifo_put(fifo_t *fifo, char byte)
{
while (fifo_full(fifo))
{
fifo_get(fifo);
}
fifo->buf[fifo->head] = byte;
fifo->head = fifo_next(fifo, fifo->head);
}
1 change: 1 addition & 0 deletions src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ $(BUILD)/kernel.bin: \
$(BUILD)/kernel/keyboard.o \
$(BUILD)/lib/bitmap.o \
$(BUILD)/lib/list.o \
$(BUILD)/lib/fifo.o \
$(BUILD)/lib/string.o \
$(BUILD)/lib/vsprintf.o \
$(BUILD)/lib/stdlib.o \
Expand Down

0 comments on commit e8459bb

Please sign in to comment.