C++20协程
Coroutine of C++20
C++的协程是:
对称的。一个协程暂停后,可返回 caller 或恢复任意协程。
语言级特性。编译器知道你在使用协程。然而不比库强到哪里去。
无栈(Stackless) 的。没有独立运行时栈,无惧爆栈,调度成本低。
一个协程在被命令「暂停」时,会保证将数据和当前运行位置保存在堆内存(以便恢复现场),然后转移运行权。
实现协程间切换co_await Transfer{};struct promise { // ... std::coroutine_handle<promise> other;};std::coroutine_handle<> Transfer::await_suspend(std::coroutine_handle<promise> me){ return me.promise().other ? me.promise().other : me;}
缺点
除非编译器优化,每个协程都需要通过operator ...
futex
Futex
Futex(Fast userspace mutex,用户态快速互斥锁) ,是一种用户态与内核态共同作用的锁,其用户态部分负责锁逻辑,内核态部分负责锁调度。
当用户态线程请求锁时,先在用户态进行锁状态的判断维护
若此时不产生锁的竞争,则直接在用户态进行上锁返回;
反之,则需要进行线程的挂起操作,通过Futex系统调用请求内核介入来挂起线程,并维护阻塞队列。
当用户态线程释放锁时,先在用户态进行锁状态的判断维护
若此时没有其他线程被该锁阻塞,则直接在用户态进行解锁返回;
反之,则需要进行阻塞线程的唤醒操作,通过Futex系统调用请求内核介入来唤醒阻塞队列中的线程。
/// 快速系统调用static int futex(uint32_t *uaddr, int futex_op, uint32_t val, const struct timespec *timeout, uint32_t *uaddr2, uint32_t val3) { return syscall(SYS_futex ...
Why we need memory barrier?
Why we need memory barrier?MESI protocol state
状态
描述
监听任务
M 修改 (Modified)
该Cache line有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。
缓存行必须时刻监听所有试图读该缓存行相对就主存的操作,这种操作必须在缓存将该缓存行写回主存并将状态变成S(共享)状态之前被延迟执行。
E 独享、互斥 (Exclusive)
该Cache line有效,数据和内存中的数据一致,数据只存在于本Cache中。
缓存行也必须监听其它缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成S(共享)状态。
S 共享 (Shared)
该Cache line有效,数据和内存中的数据一致,数据存在于很多Cache中。
缓存行也必须监听其它缓存使该缓存行无效或者独享该缓存行的请求,并将该缓存行变成无效(Invalid)。
I 无效 (Invalid)
该Cache line无效。
无
Stores Result in Unnecessary Stalls
针对某些特定地址的数据(在一 ...
BatchOS
BatchOS
实现批处理程序功能的OS
APP与OS隔离
自动加载并运行多个程序
特权级机制
ecall 具有用户态到内核态的执行环境切换能力的函数调用指令;
sret :具有内核态到用户态的执行环境切换能力的函数返回指令。
首先,操作系统需要提供相应的功能代码,能在执行 sret 前准备和恢复用户态执行应用程序的上下文。其次,在应用程序调用 ecall 指令后,能够检查应用程序的系统调用参数,确保参数不会破坏操作系统。
RISC-V异常
RISC-V S模式特权指令
sert:从S模式返回U模式
wfi:处理器在空闲时进入低功耗状态等待终端
sfence.vma:刷新TLB缓存
访问S模式CSR指令:改变系统状态
控制状态寄存器
sstatus:SPP字段给出Trap发生前CPU的特权级
sepc:记录异常发生前执行的最后一条指令的地址
scause:描述Trap的原因
stval:给出Trap的附加信息
stvec:控制Trap处理代码的入口地址
硬件切换的硬件控制机制ecall
sstatus中的SPP字段切换到CPU当前特权级
sepc修改为Trap处理完成后默认 ...
LibOS
LibOS
实现与OS无关的OS类型的程序
结构
OS在APP运行前进行初始化:建立栈空间 + .bss段清零
Bootloader在0x80000000处加载,所以OS只能在0x80200000处加载
内存布局
rustlings
RustlingsOption2
调用·vec的pop 方法时,它会从数组的末尾移除一个元素,并返回被移除的元素作为 Option<T>。因此,在这个例子中,由于数组的类型是 Vec<Option<i8>>,所以 pop 方法返回的类型是 Option<Option<i8>>
错误处理
Result<String, String>:第一个类型是Ok()中的数据类型,第二个类型是Err()中的类型
use std::fmt::Error;pub fn generate_nametag_text(name: String) -> Result<String, String> { if name.is_empty() { // Empty names aren't allowed. Err("`name` was empty; it must be nonempty.".into()) } else ...
C++内存序
C++11并发操作的内存序原子操作的关系Synchronized-with
If thread A stores a value and thread B reads that value, there’s a synchronizes-with relationship between the store in thread A and the load in thread B.
Happens-before
单线程:如果一个操作 A 排列在另一个操作 B 之前,那么这个操作 A happens-before B,一般单线程叫A sequenced-before B。
多线程:对于多线程而言, 如果一个线程中的操作A先于另一个线程中的操作B, 那么 A happens-before B(一般多线程间操作叫A inter-thread happens-before B)。
六种内存顺序typedef enum memory_order { memory_order_relaxed, // 无同步或顺序限制,只保证当前操作原子性 memory_order_consum ...
协程
协程
可以实现暂停和恢复的函数
暂停可能的动作
回到调度器(a),go语言
回到caller(c),python yield
恢复另一个协程(s)
调度器
挑选合适的协程来运行
当d需要暂停时,bcd整个调用链条都会被暂停
非对称协程
如果允许父子协程相互调用,可能会爆栈
对称协程
协程间没有明确的父子关系
无栈协程与有栈协程
无栈协程会定义自己的协程帧;有栈协程可以看作为函数,在自己分配的栈空间上运行
Hello World
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick StartCreate a new post$ hexo new "My New Post"
More info: Writing
Run server$ hexo server
More info: Server
Generate static files$ hexo generate
More info: Generating
Deploy to remote sites$ hexo deploy
More info: Deployment
6_Hash_Table
6 Hash Table使用范围
Internal Meta-data
Core Data Storage
Temporary Data Structures (join 联表查询)
Table Indexes
6.1 Design Decisions
Data Organization
Concurrency
unrealistic assumptions
Hash Function
计算速度和碰撞率的取舍
Hashing Scheme
静态哈希表
可扩展哈希表
6.2 hash functions
6.3 static Hashing SchemesLinear probe hashing (线性探测哈希)如果碰撞,存放到下一个空闲的槽;可能出现原来存在冲突的值被删除
Tombstone (墓碑):标记该位置有值被删除
Movement:将空槽之后的数据进行整理
重复的键问题
Separate Linked List:把每个键对应的键值存在特殊结构中,hash 表中存放指向该结构的指针
Redundant Keys:将键值一起作为键,存放在哈希 ...