OSDN Git Service

* config/i386/sse.md (sseintprefix): Rename from gthrfirstp.
[pf3gnuchains/gcc-fork.git] / libgo / syscalls / syscall.go
1 // syscall.go -- Basic syscall interface.
2
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.
6
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
15
16 import (
17         "sync"
18         "unsafe"
19 )
20
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");
23
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);
35   }
36   return r, 0, uintptr(GetErrno());
37 }
38
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);
49   }
50   return r, 0, uintptr(GetErrno());
51 }
52
53 // Mmap manager, for use by operating system-specific implementations.
54
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
60 }
61
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
65         }
66
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
71         }
72
73         // Slice memory layout
74         var sl = struct {
75                 addr uintptr
76                 len  int
77                 cap  int
78         }{addr, length, length}
79
80         // Use unsafe to turn sl into a []byte.
81         b := *(*[]byte)(unsafe.Pointer(&sl))
82
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
89 }
90
91 func (m *mmapper) Munmap(data []byte) (errno int) {
92         if len(data) == 0 || len(data) != cap(data) {
93                 return EINVAL
94         }
95
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
103         }
104
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
108         }
109         m.active[p] = nil, false
110         return 0
111 }