3.5 不安全过程 ¶
(loko system unsafe) 库提供了对内核服务、线性内存和 I/O 总线寄存器的原始访问。
- Procedure: syscall n arg … ¶
使用参数 arg … 调用内核的系统调用号 n。返回一个 fixnum。
在 Linux amd64 上的 fork 示例:
(when (zero? (syscall 57)) ; __NR_fork
(display "child process\n")
(exit)) ; 子进程成为僵尸进程
Scheme 程序通常不应直接使用系统调用编写,就像 C 程序不应该这样做一样。通常需要考虑与标准库的交互,例如刷新端口以防止重复输出。
- Procedure: bytevector-address bytevector ¶
获取 bytevector 的第一个字节的线性地址。
第一个字节保证具有八字节对齐。
对于使用 make-bytevector 创建的 bytevector,使用移动式垃圾回收器。没有办法确保它们在 GC 期间不会移动,因此它们的地址不应用于执行总线主控 DMA。
返回一个 fixnum。
- Procedure: get-mem-u8 addr ¶
- Procedure: get-mem-u16 addr ¶
- Procedure: get-mem-u32 addr ¶
- Procedure: get-mem-s61 addr ¶
分别从线性地址 addr 读取 u8、u16、u32 或 s61,并将其作为 fixnum 返回。
- 如果 addr 未对齐,则引发异常。
- 在 fixnum 不够宽以容纳结果的目标上,将使用大整数代替,但总线访问将是正确的宽度。
- 对这些过程的调用不会被编译器优化掉或重新排序。
- 每次调用对应于一次匹配大小的内存读取指令。对于有符号的 61 位过程,这仅适用于可以发出 64 位内存总线操作的目标。
- 这些调用可能被处理器乱序执行或进入缓存。这通常仅在内存区域由 RAM 支持时才会成为问题。在 AMD64 上,由于 MTRR,使用这些过程读取内存映射硬件寄存器是安全的。其他情况可能需要锁定指令或内存屏障。
- Procedure: put-mem-u8 addr n ¶
- Procedure: put-mem-u16 addr n ¶
- Procedure: put-mem-u32 addr n ¶
- Procedure: put-mem-s61 addr n ¶
分别将 n 作为 u8、u16、u32 或 s61 写入线性地址 addr。
- 如果 addr 未对齐,则引发异常。
- 对这些过程的调用不会被编译器优化掉或重新排序。
- 每次调用对应于一次匹配大小的内存写入指令。对于有符号的 61 位过程,这仅适用于可以发出 64 位内存总线操作的目标。
- 这些调用可能被处理器乱序执行或合并。这通常仅在内存区域由 RAM 支持时才会成为问题。在 AMD64 上,由于 MTRR,使用这些过程读取内存映射硬件寄存器是安全的。其他情况可能需要锁定指令、手动刷新或内存屏障。
返回未指定的值。
- Procedure: get-i/o-u8 busaddr ¶
- Procedure: get-i/o-u16 busaddr ¶
- Procedure: get-i/o-u32 busaddr ¶
分别从 I/O 总线地址 busaddr 读取 u8、u16 或 u32,并将其作为 fixnum 返回。
在 (<= (fixnum-width) 32) 的目标上,get-i/o-u32 过程可能返回大整数,但总线访问将是 32 位的。
- Procedure: put-i/o-u8 busaddr n ¶
- Procedure: put-i/o-u16 busaddr n ¶
- Procedure: put-i/o-u32 busaddr n ¶
分别将 n 作为 u8、u16 或 u32 写入 I/O 总线地址 busaddr。
返回未指定的值。
- Procedure: get-i/o-u8-n! busaddr addr n ¶
- Procedure: get-i/o-u16-n! busaddr addr n ¶
- Procedure: get-i/o-u32-n! busaddr addr n ¶
-
从 I/O 总线地址 busaddr 读取 n 个 u8、u16 或 u32 单元,并将其写入从线性地址 addr 开始的内存。
地址 addr 必须自然对齐到写入的大小。否则引发 &assertion。
返回未指定的值。
- Procedure: put-i/o-u8-n busaddr addr n ¶
- Procedure: put-i/o-u16-n busaddr addr n ¶
- Procedure: put-i/o-u32-n busaddr addr n ¶
-
将 n 个 u8、u16 或 u32 单元写入 I/O 总线地址 busaddr,同时从线性地址 addr 开始的内存读取它们。
地址 addr 必须自然对齐到读取的大小。否则引发 &assertion。
返回未指定的值。