Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / runtime / runtime.c
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include <unistd.h>
6
7 #include "config.h"
8
9 #include "runtime.h"
10 #include "array.h"
11 #include "go-panic.h"
12
13 int32
14 runtime_gotraceback(void)
15 {
16         const byte *p;
17
18         p = runtime_getenv("GOTRACEBACK");
19         if(p == nil || p[0] == '\0')
20                 return 1;       // default is on
21         return runtime_atoi(p);
22 }
23
24 static int32    argc;
25 static byte**   argv;
26
27 extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args");
28 extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs");
29
30 void (*runtime_sysargs)(int32, uint8**);
31
32 void
33 runtime_args(int32 c, byte **v)
34 {
35         argc = c;
36         argv = v;
37         if(runtime_sysargs != nil)
38                 runtime_sysargs(c, v);
39 }
40
41 byte*
42 runtime_progname()
43 {
44   return argc == 0 ? nil : argv[0];
45 }
46
47 void
48 runtime_goargs(void)
49 {
50         String *s;
51         int32 i;
52
53         // for windows implementation see "os" package
54         if(Windows)
55                 return;
56
57         s = runtime_malloc(argc*sizeof s[0]);
58         for(i=0; i<argc; i++)
59                 s[i] = runtime_gostringnocopy((const byte*)argv[i]);
60         os_Args.__values = (void*)s;
61         os_Args.__count = argc;
62         os_Args.__capacity = argc;
63 }
64
65 void
66 runtime_goenvs_unix(void)
67 {
68         String *s;
69         int32 i, n;
70
71         for(n=0; argv[argc+1+n] != 0; n++)
72                 ;
73
74         s = runtime_malloc(n*sizeof s[0]);
75         for(i=0; i<n; i++)
76                 s[i] = runtime_gostringnocopy(argv[argc+1+i]);
77         syscall_Envs.__values = (void*)s;
78         syscall_Envs.__count = n;
79         syscall_Envs.__capacity = n;
80 }
81
82 int32
83 runtime_atoi(const byte *p)
84 {
85         int32 n;
86
87         n = 0;
88         while('0' <= *p && *p <= '9')
89                 n = n*10 + *p++ - '0';
90         return n;
91 }
92
93 uint32
94 runtime_fastrand1(void)
95 {
96         M *m;
97         uint32 x;
98
99         m = runtime_m();
100         x = m->fastrand;
101         x += x;
102         if(x & 0x80000000L)
103                 x ^= 0x88888eefUL;
104         m->fastrand = x;
105         return x;
106 }
107
108 static struct root_list runtime_roots =
109 { nil,
110   { { &syscall_Envs, sizeof syscall_Envs },
111     { &os_Args, sizeof os_Args },
112     { nil, 0 } },
113 };
114
115 void
116 runtime_check(void)
117 {
118         __go_register_gc_roots(&runtime_roots);
119 }
120
121 int64
122 runtime_cputicks(void)
123 {
124 #if defined(__386__) || defined(__x86_64__)
125   uint32 low, high;
126   asm("rdtsc" : "=a" (low), "=d" (high));
127   return (int64)(((uint64)high << 32) | (uint64)low);
128 #else
129   // FIXME: implement for other processors.
130   return 0;
131 #endif
132 }
133
134 bool
135 runtime_showframe(String s, bool current)
136 {
137         static int32 traceback = -1;
138
139         if(current && runtime_m()->throwing > 0)
140                 return 1;
141         if(traceback < 0)
142                 traceback = runtime_gotraceback();
143         return traceback > 1 || (__builtin_memchr(s.str, '.', s.len) != nil && __builtin_memcmp(s.str, "runtime.", 7) != 0);
144 }
145
146 static Lock ticksLock;
147 static int64 ticks;
148
149 int64
150 runtime_tickspersecond(void)
151 {
152         int64 res, t0, t1, c0, c1;
153
154         res = (int64)runtime_atomicload64((uint64*)&ticks);
155         if(res != 0)
156                 return ticks;
157         runtime_lock(&ticksLock);
158         res = ticks;
159         if(res == 0) {
160                 t0 = runtime_nanotime();
161                 c0 = runtime_cputicks();
162                 runtime_usleep(100*1000);
163                 t1 = runtime_nanotime();
164                 c1 = runtime_cputicks();
165                 if(t1 == t0)
166                         t1++;
167                 res = (c1-c0)*1000*1000*1000/(t1-t0);
168                 if(res == 0)
169                         res++;
170                 runtime_atomicstore64((uint64*)&ticks, res);
171         }
172         runtime_unlock(&ticksLock);
173         return res;
174 }
175
176 int64 runtime_pprof_runtime_cyclesPerSecond(void)
177      __asm__ (GOSYM_PREFIX "runtime_pprof.runtime_cyclesPerSecond");
178
179 int64
180 runtime_pprof_runtime_cyclesPerSecond(void)
181 {
182         return runtime_tickspersecond();
183 }