OS

操作系统课程2024-17

C 标准库设计与实现

Posted by BY morningcat on May 6, 2024

关于 PIPE

查看手册

man 7 pipe

Broken pipe问题

python3 -c 'while True: print(1)' | head -n 1

> python3 -c 'while True: print(1)' | head -n 1
1
Traceback (most recent call last):
  File "<string>", line 1, in <module>
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipeError: [Errno 32] Broken pipe

(yes; echo $? > /dev/stderr) | head -n 1

> (yes; echo $? > /dev/stderr) | head -n 1
y
141

关于 _start

void main(){

}

void _start(){
    main();
    // handle
    systemcall(SYS_exit, 0);
}

gcc -Wall -g -ffreestanding -nostdlib -static sh.c -o sh

glibc

libc是Standard C library的简称; libc库提供C语言中所使用的宏,类型定义,字符串操作函数,数学计算函数以及输入输出函数等。 我们在Linux操作系统下所说的libc即glibc, glibc是类Unix操作系统中使用最广泛的libc库,它的全称是GNU C Library。

glibc是GNU工具链的关键组件,用于和二进制工具和编译器一起使用,为目标架构生成用户空间应用程序。 当从源码进行构建时,一些Linux程序可能需要链接到某个特定版本的glibc。

ldd –version

/lib/x86_64-linux-gnu/libc.so.6

  • https://www.gnu.org/software/libc/
  • https://ftp.gnu.org/gnu/libc/

在这里插入图片描述

musl libc

musl is an implementation of the C standard library built on top of the Linux system call API

https://musl.libc.org/

which mush-gcc

cat (which mush-gcc)

Freestanding 环境

  • https://zh.cppreference.com/w/cpp/freestanding
  • https://cplusplus.com/reference/cinttypes/

FILE

#include <stdio.h>

int main() {
    FILE *p = fopen("1.txt","r");
    printf("*p=%p\n", p);
    if(!p){
        perror("not open");
        return 1;
    }
    return 0;
}

env

#include <stdio.h>

extern char ** environ;

int main() {
    for(char **env=environ;*env;env++){
        printf("%s\n", *env);
    }
    return 0;
}

等效于

#include <stdio.h>

int main(int argc, char *argv[], char *envp[]) {
    for(char **env=envp;*env;env++){
        printf("%s\n", *env);
    }
    return 0;
}

System V Application Binary Interface

https://jyywiki.cn/OS/manuals/sysv-abi.pdf

给libc的实现者写的,如果想要实现自己的 libc 实现,则遵守这个标准的话,代码的运行效果将与其他系统的运行效果一致.

动态内存管理

利用 mmap 系统调用,自己实现 malloc 和 free 函数

脱离 workload 做优化就是耍流氓

去哪里找 workload? 当然是 paper 了

Mimalloc: free list sharding in action (APLAS’19) or

Thinking, Fast and Slow by Daniel Kahneman

  • Fast path (System I) 性能极好、并行度极高、覆盖大部分情况 ; 但有小概率会失败
  • Slow path (System II) 不在乎那么快, 但不会失败

malloc: Fast Path 设计

  • 线程都事先瓜分一些 “领地” (thread-local allocation buffer)
  • 默认从自己的领地里分配
  • 如果自己的领地不足,就从全局的池子里借一点
分配: Segregated List (Slab)
每个 slab 里的每个对象都一样大
每个线程拥有每个对象大小的 slab
fast path → 立即在线程本地分配完成
slow path → pgalloc()

动态内存管理小内存:Segregated List (cont'd)
分配: Slab
问题被简化了
一个内存页被分配成大小是 2^𝑘的分配单元
每个分配单元里塞个指针,就是 free list 了
(uintptr_t)p & 0xfff 就可以得到对应的 slab
头部可以存放一些 metadata,例如自旋锁
回收:直接归还到 slab 中
注意这可能是另一个线程持有的 slab
需要 per-slab 锁 (小心数据竞争)