qianyi

Results 91 issues of qianyi

Hi, first of all thanks for your great package. Recently leetcode seems has changed its login mechanism. When try to execute `leetcode-try` or `leetcode-submit`, the error message below ``` shell...

Hi I installed imenu-extra through melpa, and add following config in init.el ``` (add-hook 'c-mode-hook (lambda () ;; at the end of mode hook (imenu-extra-auto-setup '(("tdd.it" "^[ \t]*it('\\([^']+\\)" 1) ("tdd.desc"...

由于各种限制,中断处理程序只能构成任何中断处理流程的前半部分。 中断是异步发生的,为了避免打断其他代码执行路径(包括启动中断处理),中断处理程序需要尽可能执行得快。 中断处理默认会关闭当前中断,如果中断迟迟执行不完,会导致中断关闭时间过长,这对一些时间敏感的任务是很不友好的,比如网络,关中断太长可能导致丢包。 # Bottom Halves 中断处理程序一般需要回复硬件收到了中断,也有可能需要从硬件拷贝数据。没有绝对的界限说哪些事情应该在上半部,哪些应该在下半部。一些区分上下半部的建议: - If the work is time sensitive, perform it in the interrupt handler. - If the work is related to the hardware, perform...

Linux 内核实现了一种称为页面缓存(page cache)的磁盘缓存。这个缓存的目标是通过将数据存储在物理内存中来最小化磁盘 I/O,否则这些数据将需要访问磁盘。 为什么要有页面缓存?1.内存访问速度比硬盘快得多。2.时间和空间局部性原理。 ## 缓存方法 页面缓存由 RAM 中的物理页面组成,其内容对应于磁盘上的物理块 > For example, when a process issues the read() system call—it first checks if the requisite data is in the...

# 地址空间 进程地址空间由进程可寻址的虚拟内存和允许进程使用的虚拟内存中的地址组成。每个进程都有32或64位的地址空间,取决于具体架构。进程可以选择与其他进程共享它们的地址空间,我们将这些进程称为线程。以4GB(32位)地址空间为例,进程虽然有这么大的地址空间,但并不能访问全部内容。地址空间内能访问的范围称为`memory areas`,进程和内核可以动态增加或者删除内存区域。内存区域具有关联的权限,例如可读、可写和可执行,关联进程必须遵守这些权限。内存区域可以包含如下内容 ![image](https://user-images.githubusercontent.com/8001473/125926267-8b0acff5-5c11-4a18-948e-bbdf9a50eb21.png) # 内存描述符 内核用称为内存描述符的数据结构表示进程的地址空间,这个结构包含进程地址空间的所有信息,由`struct mm_struct`表示。 ```C // struct mm_struct { struct vm_area_struct *mmap; /* list of memory areas */ struct rb_root mm_rb; /* red-black tree of...

块设备是硬件设备,以固定大小的数据块的随机(即不一定顺序)访问为特征。固定大小的块称为`blocks`。另外一种设备是字符设备,字符设备是数据流顺序访问设备,比如键盘、串口。 # 解剖块设备 块设备最小寻址单元是扇区,扇区一般是2的幂次方,一般是512字节。扇区是块设备的物理属性和基本组成单元。设备不能寻址或操作小于扇区的单元,但可以是几个扇区。软件最小的寻址单元是`block`。块是文件系统的抽象——文件系统只能以块的倍数访问。虽然物理设备在扇区级别可寻址,但内核以块为单位执行所有磁盘操作。块必须是扇区的倍数,同时内核也要求块不能超过一页大小。常见的块大小为 512 字节、1 KB 和 4 KB。扇区对内核之所以重要是因为所有设备 I/O 都必须以扇区为单位进行。 # Buffers and Buffer Heads 当一个块存储在内存中时——比如说,在读取或等待写入之后——它存储在`buffer`中。每一个buffer对应一个block,buffer代表内存中磁盘块的对象。一个页面能包含一个或多个block。因为内核要求数据的一些控制信息(例如来自哪个块设备和这个块设备对应的buffer是哪个),每个buffer有一个描述符,称为`buffer head`,由`struct buffer_head`表示。buffer_head包含内核需要操作buffer的所有信息。 ```C #include struct buffer_head { unsigned long b_state; /* buffer...

虚拟文件系统(有时称为虚拟文件交换机或更常见的简称为 VFS)是内核的子系统,它实现了提供给用户空间程序的文件和文件系统相关接口 ## 通用文件系统接口 VFS 是一种粘合剂,它使 open()、read() 和 write() 等系统调用能够在不考虑文件系统或底层物理介质的情况下工作。VFS 和块 I/O 层一起提供了抽象、接口和粘合,允许用户空间程序发出通用系统调用以通过任何文件系统上的统一命名策略访问文件,文件系统本身存在于任何存储介质上。 ## 文件系统抽象层 这种适用于任何类型文件系统的通用接口之所以可行,只是因为内核围绕其低级文件系统接口实现了一个抽象层。抽象层通过定义所有文件系统支持的基本概念接口和数据结构来工作。实际上,除了文件系统本身之外,内核中没有任何东西需要了解文件系统的底层细节。比如 ```C ret = write (fd, buf, len); ``` 流程如下图 ![image](https://user-images.githubusercontent.com/8001473/125469378-6c38f80a-889b-4a07-80d9-766c8aa46b3f.png) ## Unix文件系统 历史上,Unix提供了4个基本文件系统抽象:`files, directory...

# Pages 内核将物理页面作为基本内存管理单元。内核中页面由`struct page`结构表示,简化后的定义如下 ```C struct page { unsigned long flags; atomic_t _count; atomic_t _mapcount; unsigned long private; struct address_space *mapping; pgoff_t index; struct list_head lru; void *virtual; }; ```...

时间对内核是很重要的,很多功能都由时间驱动,比如均衡调度队列,刷新屏幕等。 ## 内核时间表示 `system timer`以预先设定好的频率触发称为`tick rate`。内核里面有两种时间, `wall time`和`system time`。 > Wall time—the actual time of day—is important to user-space applications. The system uptime—the relative time since the system booted—is useful...

# 原子操作 Atomic operations provide instructions that execute **atomically**—without interruption. 内核提高了两种原子操作,一种是对整数操作,一种是对比特位操作。一些体系架构提高了原子操作指令,而一些架构则是通过Lock内存总线来实现的。 ## 原子整数操作 原子整数操作由`atomic_t`表示。 ```C typedef struct { volatile int counter; }atomic_t ``` 定义及操作原子变量示例: ```C atomic_t v; /* define v...