2011-10-08 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libgo / syscalls / syscall.go
blob8c7a7ba5fee18ac3700358a290ba9a038a95cf38
1 // syscall.go -- Basic syscall interface.
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // This package contains an interface to the low-level operating system
8 // primitives. The details vary depending on the underlying system.
9 // Its primary use is inside other packages that provide a more portable
10 // interface to the system, such as "os", "time" and "net". Use those
11 // packages rather than this one if you can.
12 // For details of the functions and data types in this package consult
13 // the manuals for the appropriate operating system.
14 package syscall
16 import (
17 "sync"
18 "unsafe"
21 func libc_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32 __asm__ ("syscall");
22 func libc_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64 __asm__ ("syscall");
24 // Do a system call. We look at the size of uintptr to see how to pass
25 // the arguments, so that we don't pass a 64-bit value when the function
26 // expects a 32-bit one.
27 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
28 var r uintptr;
29 if unsafe.Sizeof(r) == 4 {
30 r1 := libc_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0);
31 r = uintptr(r1);
32 } else {
33 r1 := libc_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0);
34 r = uintptr(r1);
36 return r, 0, uintptr(GetErrno());
39 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
40 var r uintptr;
41 if unsafe.Sizeof(r) == 4 {
42 r1 := libc_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
43 int32(a4), int32(a5), int32(a6));
44 r = uintptr(r1);
45 } else {
46 r1 := libc_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
47 int64(a4), int64(a5), int64(a6));
48 r = uintptr(r1);
50 return r, 0, uintptr(GetErrno());
53 // Mmap manager, for use by operating system-specific implementations.
55 type mmapper struct {
56 sync.Mutex
57 active map[*byte][]byte // active mappings; key is last byte in mapping
58 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, int)
59 munmap func(addr uintptr, length uintptr) int
62 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, errno int) {
63 if length <= 0 {
64 return nil, EINVAL
67 // Map the requested memory.
68 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
69 if errno != 0 {
70 return nil, errno
73 // Slice memory layout
74 var sl = struct {
75 addr uintptr
76 len int
77 cap int
78 }{addr, length, length}
80 // Use unsafe to turn sl into a []byte.
81 b := *(*[]byte)(unsafe.Pointer(&sl))
83 // Register mapping in m and return it.
84 p := &b[cap(b)-1]
85 m.Lock()
86 defer m.Unlock()
87 m.active[p] = b
88 return b, 0
91 func (m *mmapper) Munmap(data []byte) (errno int) {
92 if len(data) == 0 || len(data) != cap(data) {
93 return EINVAL
96 // Find the base of the mapping.
97 p := &data[cap(data)-1]
98 m.Lock()
99 defer m.Unlock()
100 b := m.active[p]
101 if b == nil || &b[0] != &data[0] {
102 return EINVAL
105 // Unmap the memory and update m.
106 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != 0 {
107 return errno
109 m.active[p] = nil, false
110 return 0