| // Copyright 2010 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package runtime |
| #include "runtime.h" |
| #include "arch_GOARCH.h" |
| #include "type.h" |
| |
| func GOMAXPROCS(n int) (ret int) { |
| ret = runtime·gomaxprocsfunc(n); |
| } |
| |
| func NumCPU() (ret int) { |
| ret = runtime·ncpu; |
| } |
| |
| func NumCgoCall() (ret int64) { |
| M *mp; |
| |
| ret = 0; |
| for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink) |
| ret += mp->ncgocall; |
| } |
| |
| func newParFor(nthrmax uint32) (desc *ParFor) { |
| desc = runtime·parforalloc(nthrmax); |
| } |
| |
| func parForSetup(desc *ParFor, nthr uint32, n uint32, ctx *byte, wait bool, body *byte) { |
| runtime·parforsetup(desc, nthr, n, ctx, wait, *(void(**)(ParFor*, uint32))body); |
| } |
| |
| func parForDo(desc *ParFor) { |
| runtime·parfordo(desc); |
| } |
| |
| func parForIters(desc *ParFor, tid uintptr) (start uintptr, end uintptr) { |
| runtime·parforiters(desc, tid, &start, &end); |
| } |
| |
| func gogoBytes() (x int32) { |
| x = RuntimeGogoBytes; |
| } |
| |
| func typestring(e Eface) (s String) { |
| s = *e.type->string; |
| } |
| |
| func golockedOSThread() (ret bool) { |
| ret = runtime·lockedOSThread(); |
| } |
| |
| func NumGoroutine() (ret int) { |
| ret = runtime·gcount(); |
| } |
| |
| func getgoroot() (out String) { |
| byte *p; |
| |
| p = runtime·getenv("GOROOT"); |
| out = runtime·gostringnocopy(p); |
| } |
| |
| /* |
| * We assume that all architectures turn faults and the like |
| * into apparent calls to runtime.sigpanic. If we see a "call" |
| * to runtime.sigpanic, we do not back up the PC to find the |
| * line number of the CALL instruction, because there is no CALL. |
| */ |
| void runtime·sigpanic(void); |
| |
| func Caller(skip int) (retpc uintptr, retfile String, retline int, retbool bool) { |
| Func *f, *g; |
| uintptr pc; |
| uintptr rpc[2]; |
| |
| /* |
| * Ask for two PCs: the one we were asked for |
| * and what it called, so that we can see if it |
| * "called" sigpanic. |
| */ |
| retpc = 0; |
| if(runtime·callers(1+skip-1, rpc, 2) < 2) { |
| retfile = runtime·emptystring; |
| retline = 0; |
| retbool = false; |
| } else if((f = runtime·findfunc(rpc[1])) == nil) { |
| retfile = runtime·emptystring; |
| retline = 0; |
| retbool = true; // have retpc at least |
| } else { |
| retpc = rpc[1]; |
| pc = retpc; |
| g = runtime·findfunc(rpc[0]); |
| if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·sigpanic)) |
| pc--; |
| retline = runtime·funcline(f, pc, &retfile); |
| retbool = true; |
| } |
| } |
| |
| func Callers(skip int, pc Slice) (retn int) { |
| // runtime.callers uses pc.array==nil as a signal |
| // to print a stack trace. Pick off 0-length pc here |
| // so that we don't let a nil pc slice get to it. |
| if(pc.len == 0) |
| retn = 0; |
| else |
| retn = runtime·callers(skip, (uintptr*)pc.array, pc.len); |
| } |
| |
| func runtime∕pprof·runtime_cyclesPerSecond() (res int64) { |
| res = runtime·tickspersecond(); |
| } |
| |
| func sync·runtime_procPin() (p int) { |
| M *mp; |
| |
| mp = m; |
| // Disable preemption. |
| mp->locks++; |
| p = mp->p->id; |
| } |
| |
| func sync·runtime_procUnpin() { |
| m->locks--; |
| } |