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