TreeviewCopyright @doctording all right reserved, powered by aleen42

缓冲区

在键盘上操作是为了与系统进行交互,交互的过程一般是键入各种 shell 命令,然后 shell 解析并执行。shell 命令是由多个字符组成的,并且要以回车键结束,因此咱们在键入命令的过程中,必须要找个缓冲区把己键入的信息存起来,当凑成完整的命令名时再一并由其它模块处理。

生产者/消费者问题实践

缓冲区中有数据时,消费者可以消费;缓冲区有空位时,生产者可以生成(信号量可以解决生产者消费者问题)

  • 利用双向链表实现环形缓冲区

  • 数据结构和方法
#define bufsize 64

/* 环形队列 */
struct ioqueue {
// 生产者消费者问题
    struct lock lock;
 /* 生产者,缓冲区不满时就继续往里面放数据,
  * 否则就睡眠,此项记录哪个生产者在此缓冲区上睡眠。*/
    struct task_struct* producer;

 /* 消费者,缓冲区不空时就继续从往里面拿数据,
  * 否则就睡眠,此项记录哪个消费者在此缓冲区上睡眠。*/
    struct task_struct* consumer;
    char buf[bufsize];                // 缓冲区大小
    int32_t head;                // 队首,数据往队首处写入
    int32_t tail;                // 队尾,数据从队尾处读出
};

void ioqueue_init(struct ioqueue* ioq);
bool ioq_full(struct ioqueue* ioq);
bool ioq_empty(struct ioqueue* ioq);

/* 消费者从ioq队列中获取一个字符 */
char ioq_getchar(struct ioqueue* ioq);

/* 生产者往ioq队列中写入一个字符byte */
void ioq_putchar(struct ioqueue* ioq, char byte);

让键盘缓冲区成为全局的,生产消费都操作

  • 主程序验证
#include "print.h"
#include "init.h"
#include "thread.h"
#include "interrupt.h"
#include "console.h"

/* 临时为测试添加 */
#include "ioqueue.h"
#include "keyboard.h"

void k_thread_a(void*);
void k_thread_b(void*);

int main(void) {
   put_str("I am kernel\n");
   init_all();
   thread_start("consumer_a", 31, k_thread_a, " A_");
   thread_start("consumer_b", 31, k_thread_b, " B_");
   intr_enable();
   while(1);
   return 0;
}

/* 在线程中运行的函数 */
void k_thread_a(void* arg) {
   while(1) {
      enum intr_status old_status = intr_disable();
      if (!ioq_empty(&kbd_buf)) {
         console_put_str(arg);
         char byte = ioq_getchar(&kbd_buf);
         console_put_char(byte);
      }
      intr_set_status(old_status);
   }
}

/* 在线程中运行的函数 */
void k_thread_b(void* arg) {
   while(1) {
      enum intr_status old_status = intr_disable();
      if (!ioq_empty(&kbd_buf)) {
         console_put_str(arg);
         char byte = ioq_getchar(&kbd_buf);
         console_put_char(byte);
      }
      intr_set_status(old_status);
   }
}

键盘不断的输入字母p,,屏幕交替的输出A_q B_q,ioqueue完成了缓冲区。

Copyright @doctording all right reserved,powered by Gitbookupdate at: 2020-09-05 17:25:03

results matching ""

    No results matching ""