// 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.h"
#include "go-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, wait bool, body *byte) {
	runtime_parforsetup(desc, nthr, n, wait, (const FuncVal*) 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 typestring(e Eface) (s String) {
	s = *e.__type_descriptor->__reflection;
}

func golockedOSThread() (ret bool) {
	ret = runtime_lockedOSThread();
}

func NumGoroutine() (ret int) {
	ret = runtime_gcount();
}

func getgoroot() (out String) {
	out = runtime_getenv("GOROOT");
}

func runtime_pprof.runtime_cyclesPerSecond() (res int64) {
	res = runtime_tickspersecond();
}

func sync.runtime_procPin() (p int) {
	M *mp;

	mp = runtime_m();
	// Disable preemption.
	mp->locks++;
	p = mp->p->id;
}

func sync.runtime_procUnpin() {
	runtime_m()->locks--;
}

func sync_atomic.runtime_procPin() (p int) {
	M *mp;

	mp = runtime_m();
	// Disable preemption.
	mp->locks++;
	p = mp->p->id;
}

func sync_atomic.runtime_procUnpin() {
	runtime_m()->locks--;
}

extern Slice envs;

func envs() (s Slice) {
	s = envs;
}

func setenvs(e Slice) {
	envs = e;
}
