| // Copyright 2009 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. |
| |
| #include "runtime.h" |
| #include "cgocall.h" |
| |
| void *initcgo; /* filled in by dynamic linker when Cgo is available */ |
| int64 ncgocall; |
| void ·entersyscall(void); |
| void ·exitsyscall(void); |
| |
| void |
| cgocall(void (*fn)(void*), void *arg) |
| { |
| if(initcgo == nil) |
| throw("cgocall unavailable"); |
| |
| ncgocall++; |
| |
| /* |
| * Announce we are entering a system call |
| * so that the scheduler knows to create another |
| * M to run goroutines while we are in the |
| * foreign code. |
| */ |
| ·entersyscall(); |
| runcgo(fn, arg); |
| ·exitsyscall(); |
| return; |
| } |
| |
| void |
| ·Cgocalls(int64 ret) |
| { |
| ret = ncgocall; |
| FLUSH(&ret); |
| } |
| |
| void (*_cgo_malloc)(void*); |
| void (*_cgo_free)(void*); |
| |
| void* |
| cmalloc(uintptr n) |
| { |
| struct a { |
| uint64 n; |
| void *ret; |
| } a; |
| |
| a.n = n; |
| a.ret = nil; |
| cgocall(_cgo_malloc, &a); |
| return a.ret; |
| } |
| |
| void |
| cfree(void *p) |
| { |
| cgocall(_cgo_free, p); |
| } |
| |