复习
本次课回答的问题
本次课主要内容
“裸奔” 编程:能用 (而且绝对够用),但不好用
long syscall(int num, ...) {
va_list ap;
va_start(ap, num);
register long a0 asm ("rax") = num;
register long a1 asm ("rdi") = va_arg(ap, long);
register long a2 asm ("rsi") = va_arg(ap, long);
register long a3 asm ("rdx") = va_arg(ap, long);
register long a4 asm ("r10") = va_arg(ap, long);
va_end(ap);
asm volatile("syscall"
: "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4)
: "memory", "rcx", "r8", "r9", "r11");
return a0;
}
Freestanding 环境下也可以使用的定义
系统调用是操作系统 “紧凑” 的最小接口。并不是所有系统调用都像 fork 一样可以直接使用。
低情商 API:
extern char **environ;
char *argv[] = { "echo", "hello", "world", NULL, };
if (execve(argv[0], argv, environ) < 0) {
perror("exec");
}
高情商 API:
execlp("echo", "echo", "hello", "world", NULL);
system("echo hello world");
简单,不简单
void *memset(void *s, int c, size_t n) {
for (size_t i = 0; i < n; i++) {
((char *)s)[i] = c;
}
return s;
}
让我们看看 clang 把它编译成了什么……
低情商 (低配置) API
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
高情商 API
sort(xs.begin(), xs.end(), [] (auto& a, auto& b) {...});
xs.sort(lambda key=...)
RTFM!
FILE *
背后其实是一个文件描述符
FILE *
(例如 stdout)vprintf 系列
stdarg.h
的参数列表int vfprintf(FILE *stream, const char *format, va_list ap);
int vasprintf(char **ret, const char *format, va_list ap);
我们在 dosbox-hack.c 中使用了它
高情商 API (现代编程语言)
subprocess.check_output(['cat'],
input=b'Hello World', stderr=subprocess.STDOUT)
let dir_checksum = {
Exec::shell("find . -type f")
| Exec::cmd("sort") | Exec::cmd("sha1sum")
}.capture()?.stdout_str();
所有 API 都可能失败
$ gcc nonexist.c
gcc: error: nonexist.c: No such file or directory
这个 “No such file or directory” 似乎见得有点多?
cat nonexist.c, wc nonexist.c
都是同样的 error messagewarn("%s", fname);
(观察 strace)err
可以额外退出程序Specification 很简单 (同 Lab1)
$$ M = \big\{ [\ell_0, r_0), [\ell_1, r_1), \ldots, [\ell_n, r_n) \big\}$$
多线程安全
Premature optimization is the root of all evil.
——D. E. Knuth
重要的事情说三遍:
然后,去哪里找 workload?
指导思想:$O(n)$ 大小的对象分配后至少有 $\Omega(n)$ 的读写操作,否则就是 performance bug (不应该分配那么多)。
malloc
, Fast and Slow设置两套系统:
人类也是这样的系统
malloc
: Fast Path 设计不要在乎一点小的浪费
分配: Segregated List (Slab)
回收
Buddy system (1963)
你只需要一个数据结构解决问题
以上就是所有现代 malloc/free 实现的基础
RTFM: The GNU C Library, RTFSC: Newlib
你会发现很多宝藏
走出 C 的领域,基于 libc 实现
Eventually, (千疮百孔) 的整个计算机世界!
本次课回答的问题
Take-away messages