سؤال

During the research of my another question Go package syscall conn.Read() is non-blocking and cause high CPU usage, I read source code in syscall package.

Since I found my last issue on OS X 10.8.3, here is the source code related:

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

I have no idea what Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) means, actually I don't understand stuffs like unsafe.Pointer & Syscall(). How they works?

Besides, can anyone explain the comment // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT, how and why these things work with specific platform by different implementations? And how syscall package generate these interfaces?

If someone can explain a specific function like Read() related with syscall could be help me understand it better, thanks.

هل كانت مفيدة؟

المحلول

The Go Darwin syscall package func Read(fd int, p \[\]byte) (n int, err error) function is making a read (SYS_READ) system call:

read Mac OS X Developer Tools Manual Page

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

Read() attempts to read nbyte bytes of data from the object referenced by the descriptor fildes into the buffer pointed to by buf.

The Go Darwin syscall package Syscall function is:

// 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

نصائح أخرى

From what I understand, syscall.Syscall() is simply a way to call some system specific APIs.

For example, Windows APIs typically use the __stdcall convention, which in general we would not be able to achieve without syscall.Syscall() in Go.


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

trap: The API we want to call.

a1, a2, a3: Arguments to that API.

r1, r2, err: Whatever that API returns. There are three, but we would probably use only one of them.


That's about it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top