【问题标题】:What does "Syscall()" means in go package "syscall"?go package "syscall" 中的 "Syscall()" 是什么意思?
【发布时间】:2013-05-07 17:07:27
【问题描述】:

在研究我的另一个问题Go package syscall conn.Read() is non-blocking and cause high CPU usage时,我阅读了syscall包中的源代码。

自从我在 OS X 10.8.3 上找到我的上一期以来,这里是相关的源代码:

http://golang.org/src/pkg/syscall/zsyscall_darwin_amd64.go?h=Read#L898

我不知道Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) 是什么意思,实际上我不懂unsafe.PointerSyscall() 之类的东西。它们是如何工作的?

此外,任何人都可以解释评论// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT,这些东西如何以及为什么通过不同的实现在特定平台上工作?以及syscall 包是如何生成这些接口的?

如果有人可以解释与syscall 相关的Read() 等特定功能,可以帮助我更好地理解它,谢谢。

【问题讨论】:

  • Syscall(...) 看起来像来自 C 的旧 syscall() 函数的 Go-ish 版本。这个(可变参数)函数允许您通过提供系统调用号来执行任意系统调用(here it是 SYS_READ) 和一组参数。
  • 我想this link 会为你澄清很多。
  • syscall 包提供对低级 os 系统调用的访问。 C 语言版本在 man(2) 中(所以 man read 会告诉你 syscall.Read 的作用)——我认为它们与 Go 系统调用同名,只是没有大写字母。该文件可能是自动生成的,因为它包含许多包装不同系统调用的几乎相同的 Go 函数。

标签: linux unix go system-calls darwin


【解决方案1】:

Go Darwin syscallfunc Read(fd int, p \[\]byte) (n int, err error) 函数正在进行 read (SYS_READ) 系统调用:

read Mac OS X Developer Tools Manual Page

ssize_t read(int fildes, void *buf, size_t nbyte);

Read() 尝试从对象中读取 nbyte 字节的数据 由描述符fildes 引用到buf 指向的缓冲区中。

Go Darwin syscallSyscall 函数是:

// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
// Trap # in AX, args in DI SI DX, return in AX DX

TEXT    ·Syscall(SB),7,$0
    CALL    runtime·entersyscall(SB)
    MOVQ    16(SP), DI
    MOVQ    24(SP), SI
    MOVQ    32(SP), DX
    MOVQ    $0, R10
    MOVQ    $0, R8
    MOVQ    $0, R9
    MOVQ    8(SP), AX   // syscall entry
    ADDQ    $0x2000000, AX
    SYSCALL
    JCC ok
    MOVQ    $-1, 40(SP) // r1
    MOVQ    $0, 48(SP)  // r2
    MOVQ    AX, 56(SP)  // errno
    CALL    runtime·exitsyscall(SB)
    RET
ok:
    MOVQ    AX, 40(SP)  // r1
    MOVQ    DX, 48(SP)  // r2
    MOVQ    $0, 56(SP)  // errno
    CALL    runtime·exitsyscall(SB)
    RET

【讨论】:

    【解决方案2】:

    据我了解,syscall.Syscall() 只是调用某些系统特定 API 的一种方式。

    例如,Windows API 通常使用 __stdcall 约定,一般情况下,如果在 Go 中没有 syscall.Syscall(),我们将无法实现。


    func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)

    trap:我们要调用的API。

    a1, a2, a3:该 API 的参数。

    r1, r2, err:无论 API 返回什么。一共有三个,但我们可能只会使用其中一个。


    就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-08
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      • 2015-11-03
      • 1970-01-01
      相关资源
      最近更新 更多